Skip to content

Instantly share code, notes, and snippets.

@dnmfarrell
Last active May 13, 2022 16:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dnmfarrell/12f5497358f79619f460359d609c37ca to your computer and use it in GitHub Desktop.
Save dnmfarrell/12f5497358f79619f460359d609c37ca to your computer and use it in GitHub Desktop.
trycopy - uses a try monad to copy a file
package try // https://github.com/dnmfarrell/try
import (
"fmt"
"io"
"os"
)
// based on:
// https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling-overview.md
func Open(src string) Try[*os.File] {
r, err := os.Open(src)
if err != nil {
return Fail[*os.File](err)
}
return Succeed[*os.File](r)
}
func Copy(r, w *os.File) Try[*os.File] {
_, err := io.Copy(w, r)
r.Close()
if err != nil {
w.Close()
return Fail[*os.File](err)
}
return Succeed[*os.File](w)
}
func Close(fd *os.File) Try[int] { // should be option
err := fd.Close()
if err != nil {
return Fail[int](err)
}
return Succeed[int](0)
}
func CopyFile(src, dst string) error {
createNCopy := func(r *os.File) Try[*os.File] {
w, err := os.Create(dst)
if err != nil {
r.Close()
return Fail[*os.File](err)
}
return Copy(r, w)
}
err := Bind(Bind(Open(src), createNCopy), Close).Err
if err != nil {
os.Remove(dst)
return fmt.Errorf("copy %s %s: %v", src, dst, err)
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment