diff --git a/examples/file-replace.roc b/examples/file-replace.roc new file mode 100644 index 00000000..e8f5578f --- /dev/null +++ b/examples/file-replace.roc @@ -0,0 +1,27 @@ +## Replace every occurrence of a substring in a UTF-8 file in place. +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } + +import pf.OsStr +import pf.Stdout +import pf.Path + +main! : List(OsStr) => Try({}, _) +main! = |_args| { + + file : Path + file = "greeting.txt" + + file.write_utf8!("Hello, World! Hello, Roc!")? + + # Replaces both occurrences of "Hello", not just the first. + file.replace_utf8!("Hello", "Goodbye")? + + contents = file.read_utf8!()? + + # Cleanup + file.delete!()? + + Stdout.line!("After replacing: \"${contents}\"")? + + Ok({}) +} diff --git a/platform/Path.roc b/platform/Path.roc index 982be245..6ade3a6d 100644 --- a/platform/Path.roc +++ b/platform/Path.roc @@ -107,6 +107,18 @@ Path := [ write_utf8! : Path, Str => Try({}, [PathErr(IOErr), ..]) write_utf8! = |path, content| map_file_result(Host.file_write_utf8!(to_raw(path), content)) + ## Replace every occurrence of `pattern` with `replacement` in the UTF-8 file + ## at this path. + ## + ## This reads the whole file, substitutes, and writes it back, so it is not + ## atomic: a failure mid-write can leave the file partially written, exactly + ## as a bare [write_utf8!] would. + replace_utf8! : Path, Str, Str => Try({}, [PathErr(IOErr), ..]) + replace_utf8! = |path, pattern, replacement| { + content = read_utf8!(path)? + write_utf8!(path, Str.replace_each(content, pattern, replacement)) + } + ## Delete a file at this path. delete! : Path => Try({}, [PathErr(IOErr), ..]) delete! = |path| map_file_result(Host.file_delete!(to_raw(path))) diff --git a/scripts/test_spec.json b/scripts/test_spec.json index 25789463..9377f724 100644 --- a/scripts/test_spec.json +++ b/scripts/test_spec.json @@ -148,6 +148,18 @@ } ] }, + { + "path": "examples/file-replace.roc", + "cases": [ + { + "name": "happy", + "temp_cwd": true, + "contains": [ + "After replacing: \"Goodbye, World! Goodbye, Roc!\"" + ] + } + ] + }, { "path": "examples/file-size.roc", "cases": [