From 290c72732f21f1cddb3a0f8ec3213e4ec321da14 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sat, 15 Nov 2025 18:13:44 -0500 Subject: Add Path.lines() --- api/api.md | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- api/paths.md | 28 +++++++++++++++++++---- api/paths.yaml | 25 +++++++++++++++++---- 3 files changed, 112 insertions(+), 12 deletions(-) (limited to 'api') diff --git a/api/api.md b/api/api.md index eaf8da17..3af79d37 100644 --- a/api/api.md +++ b/api/api.md @@ -342,6 +342,49 @@ assert [x for x in Byte(2).to(5, step=2)] == [Byte(2), Byte(4)] ``` +# CString +## CString.as_text + +```tomo +CString.as_text : func(str: CString -> Text) +``` + +Convert a C string to Text. + +Argument | Type | Description | Default +---------|------|-------------|--------- +str | `CString` | The C string. | - + +**Return:** The C string as a Text. + + +**Example:** +```tomo +assert CString("Hello").as_text() == "Hello" + +``` +## CString.join + +```tomo +CString.join : func(glue: CString, pieces: [CString] -> CString) +``` + +Join a list of C strings together with a separator. + +Argument | Type | Description | Default +---------|------|-------------|--------- +glue | `CString` | The C joiner used to between elements. | - +pieces | `[CString]` | A list of C strings to join. | - + +**Return:** A C string of the joined together bits. + + +**Example:** +```tomo +assert CString(",").join([CString("a"), CString("b")]) == CString("a,b") + +``` + # Int ## Int.abs @@ -2565,14 +2608,14 @@ path | `Path` | The path of the file. | - ```tomo # Safely handle file not being readable: if lines := (./file.txt).by_line() -for line in lines -say(line.upper()) + for line in lines + say(line.upper()) else -say("Couldn't read file!") + say("Couldn't read file!") # Assume the file is readable and error if that's not the case: for line in (/dev/stdin).by_line()! -say(line.upper()) + say(line.upper()) ``` ## Path.can_execute @@ -3018,6 +3061,26 @@ path | `Path` | The path to check. | - ```tomo assert (./link).is_symlink() == yes +``` +## Path.lines + +```tomo +Path.lines : func(path: Path -> [Text]?) +``` + +Returns a list with the lines of text in a file or returns none if the file could not be opened. + +Argument | Type | Description | Default +---------|------|-------------|--------- +path | `Path` | The path of the file. | - + +**Return:** A list of the lines in a file or none if the file couldn't be read. + + +**Example:** +```tomo +lines := (./file.txt).lines()! + ``` ## Path.modified diff --git a/api/paths.md b/api/paths.md index c69e91d9..07f0560b 100644 --- a/api/paths.md +++ b/api/paths.md @@ -108,14 +108,14 @@ path | `Path` | The path of the file. | - ```tomo # Safely handle file not being readable: if lines := (./file.txt).by_line() -for line in lines -say(line.upper()) + for line in lines + say(line.upper()) else -say("Couldn't read file!") + say("Couldn't read file!") # Assume the file is readable and error if that's not the case: for line in (/dev/stdin).by_line()! -say(line.upper()) + say(line.upper()) ``` ## Path.can_execute @@ -561,6 +561,26 @@ path | `Path` | The path to check. | - ```tomo assert (./link).is_symlink() == yes +``` +## Path.lines + +```tomo +Path.lines : func(path: Path -> [Text]?) +``` + +Returns a list with the lines of text in a file or returns none if the file could not be opened. + +Argument | Type | Description | Default +---------|------|-------------|--------- +path | `Path` | The path of the file. | - + +**Return:** A list of the lines in a file or none if the file couldn't be read. + + +**Example:** +```tomo +lines := (./file.txt).lines()! + ``` ## Path.modified diff --git a/api/paths.yaml b/api/paths.yaml index 532d9c71..8fbd18dc 100644 --- a/api/paths.yaml +++ b/api/paths.yaml @@ -107,14 +107,31 @@ Path.by_line: example: | # Safely handle file not being readable: if lines := (./file.txt).by_line() - for line in lines - say(line.upper()) + for line in lines + say(line.upper()) else - say("Couldn't read file!") + say("Couldn't read file!") # Assume the file is readable and error if that's not the case: for line in (/dev/stdin).by_line()! - say(line.upper()) + say(line.upper()) + +Path.lines: + short: return the lines in a file + description: > + Returns a list with the lines of text in a file or returns none if the file + could not be opened. + return: + type: '[Text]?' + description: > + A list of the lines in a file or none if the file couldn't be read. + args: + path: + type: 'Path' + description: > + The path of the file. + example: | + lines := (./file.txt).lines()! Path.can_execute: short: check execute permissions -- cgit v1.2.3 From cb9d3b1a2c2c59c368f6121a16a9ab928b0ff951 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sun, 23 Nov 2025 00:35:05 -0500 Subject: Added Text.find(text, target, start=1) --- api/api.md | 25 +++++++++++++++++++++++++ api/text.md | 25 +++++++++++++++++++++++++ api/text.yaml | 28 ++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) (limited to 'api') diff --git a/api/api.md b/api/api.md index 3af79d37..02ad054e 100644 --- a/api/api.md +++ b/api/api.md @@ -3904,6 +3904,31 @@ remainder : Text assert "hello world".ends_with("world", &remainder) == yes assert remainder == "hello " +``` +## Text.find + +```tomo +Text.find : func(text: Text, target: Text, start: Int = 1 -> Int) +``` + +Find a substring within a text and return its index, if found. + +Argument | Type | Description | Default +---------|------|-------------|--------- +text | `Text` | The text to be searched. | - +target | `Text` | The target text to find. | - +start | `Int` | The index at which to begin searching. | `1` + +**Return:** The index where the first occurrence of `target` appears, or `none` if it is not found. + + +**Example:** +```tomo +assert "one two".find("one") == 1 +assert "one two".find("two") == 5 +assert "one two".find("three") == none +assert "one two".find("o", start=2) == 7 + ``` ## Text.from diff --git a/api/text.md b/api/text.md index 9bd99529..928cb6ec 100644 --- a/api/text.md +++ b/api/text.md @@ -204,6 +204,31 @@ remainder : Text assert "hello world".ends_with("world", &remainder) == yes assert remainder == "hello " +``` +## Text.find + +```tomo +Text.find : func(text: Text, target: Text, start: Int = 1 -> Int) +``` + +Find a substring within a text and return its index, if found. + +Argument | Type | Description | Default +---------|------|-------------|--------- +text | `Text` | The text to be searched. | - +target | `Text` | The target text to find. | - +start | `Int` | The index at which to begin searching. | `1` + +**Return:** The index where the first occurrence of `target` appears, or `none` if it is not found. + + +**Example:** +```tomo +assert "one two".find("one") == 1 +assert "one two".find("two") == 5 +assert "one two".find("three") == none +assert "one two".find("o", start=2) == 7 + ``` ## Text.from diff --git a/api/text.yaml b/api/text.yaml index 2c21fa30..6874bfc8 100644 --- a/api/text.yaml +++ b/api/text.yaml @@ -225,6 +225,34 @@ Text.ends_with: assert "hello world".ends_with("world", &remainder) == yes assert remainder == "hello " +Text.find: + short: find a substring + description: > + Find a substring within a text and return its index, if found. + return: + type: 'Int' + description: > + The index where the first occurrence of `target` appears, or `none` if it is not found. + args: + text: + type: 'Text' + description: > + The text to be searched. + target: + type: 'Text' + description: > + The target text to find. + start: + type: 'Int' + default: '1' + description: > + The index at which to begin searching. + example: | + assert "one two".find("one") == 1 + assert "one two".find("two") == 5 + assert "one two".find("three") == none + assert "one two".find("o", start=2) == 7 + Text.from: short: slice from a starting index description: > -- cgit v1.2.3 From 2a24b0a3fc3c4986572ae2c4ea0e8e387497a7f6 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sun, 23 Nov 2025 14:19:04 -0500 Subject: Add `at_cleanup()` function --- api/api.md | 26 +++++++++++++++++++++++++- api/builtins.md | 26 +++++++++++++++++++++++++- api/builtins.yaml | 28 +++++++++++++++++++++++++++- 3 files changed, 77 insertions(+), 3 deletions(-) (limited to 'api') diff --git a/api/api.md b/api/api.md index 02ad054e..5c9dc9c4 100644 --- a/api/api.md +++ b/api/api.md @@ -32,11 +32,35 @@ force_tty | `Bool` | Whether or not to force the use of /dev/tty. | `yes` ```tomo assert ask("What's your name? ") == "Arthur Dent" +``` +## at_cleanup + +```tomo +at_cleanup : func(fn: func() -> Void) +``` + +Register a function that runs at cleanup time for Tomo programs. Cleanup time happens when a program exits (see `atexit()` in C), or immediately before printing error messages in a call to `fail()`. This allows for terminal cleanup so error messages can be visible as the program shuts down. + +Use this API very carefully, because errors that occur during cleanup functions may make it extremely hard to figure out what's going on. Cleanup functions should be designed to not error under any circumstances. + +Argument | Type | Description | Default +---------|------|-------------|--------- +fn | `func()` | A function to run at cleanup time. | - + +**Return:** Nothing. + + +**Example:** +```tomo +at_cleanup(func() + (/tmp/file.txt).remove(ignore_missing=yes) +) + ``` ## exit ```tomo -exit : func(message: Text? = none, status: Int32 = Int32(1) -> Void) +exit : func(message: Text? = none, status: Int32 = Int32(1) -> Abort) ``` Exits the program with a given status and optionally prints a message. diff --git a/api/builtins.md b/api/builtins.md index 0b06a41b..6d042741 100644 --- a/api/builtins.md +++ b/api/builtins.md @@ -32,11 +32,35 @@ force_tty | `Bool` | Whether or not to force the use of /dev/tty. | `yes` ```tomo assert ask("What's your name? ") == "Arthur Dent" +``` +## at_cleanup + +```tomo +at_cleanup : func(fn: func() -> Void) +``` + +Register a function that runs at cleanup time for Tomo programs. Cleanup time happens when a program exits (see `atexit()` in C), or immediately before printing error messages in a call to `fail()`. This allows for terminal cleanup so error messages can be visible as the program shuts down. + +Use this API very carefully, because errors that occur during cleanup functions may make it extremely hard to figure out what's going on. Cleanup functions should be designed to not error under any circumstances. + +Argument | Type | Description | Default +---------|------|-------------|--------- +fn | `func()` | A function to run at cleanup time. | - + +**Return:** Nothing. + + +**Example:** +```tomo +at_cleanup(func() + (/tmp/file.txt).remove(ignore_missing=yes) +) + ``` ## exit ```tomo -exit : func(message: Text? = none, status: Int32 = Int32(1) -> Void) +exit : func(message: Text? = none, status: Int32 = Int32(1) -> Abort) ``` Exits the program with a given status and optionally prints a message. diff --git a/api/builtins.yaml b/api/builtins.yaml index 2eae5340..764a1bd4 100644 --- a/api/builtins.yaml +++ b/api/builtins.yaml @@ -38,7 +38,7 @@ exit: description: > Exits the program with a given status and optionally prints a message. return: - type: 'Void' + type: 'Abort' description: > This function never returns. args: @@ -56,6 +56,32 @@ exit: example: | exit(status=1, "Goodbye forever!") +at_cleanup: + short: register a cleanup function + description: > + Register a function that runs at cleanup time for Tomo programs. Cleanup + time happens when a program exits (see `atexit()` in C), or immediately + before printing error messages in a call to `fail()`. This allows for + terminal cleanup so error messages can be visible as the program shuts + down. + note: > + Use this API very carefully, because errors that occur during cleanup + functions may make it extremely hard to figure out what's going on. Cleanup + functions should be designed to not error under any circumstances. + args: + fn: + type: 'func()' + description: > + A function to run at cleanup time. + return: + type: 'Void' + description: > + Nothing. + example: | + at_cleanup(func() + (/tmp/file.txt).remove(ignore_missing=yes) + ) + getenv: short: get an environment variable description: > -- cgit v1.2.3 From 437be558a893ac70c030794df99a866e8ed01879 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Thu, 27 Nov 2025 12:05:49 -0500 Subject: Add `recursive` arg to Path.create_directory() --- api/api.md | 4 +++- api/paths.md | 4 +++- api/paths.yaml | 7 +++++++ 3 files changed, 13 insertions(+), 2 deletions(-) (limited to 'api') diff --git a/api/api.md b/api/api.md index 5c9dc9c4..ec6ffb49 100644 --- a/api/api.md +++ b/api/api.md @@ -2777,15 +2777,17 @@ assert (./directory).children(include_hidden=yes) == [".git", "foo.txt"] ## Path.create_directory ```tomo -Path.create_directory : func(path: Path, permissions = Int32(0o755) -> Void) +Path.create_directory : func(path: Path, permissions = Int32(0o755), recursive = yes -> Void) ``` Creates a new directory at the specified path with the given permissions. If any of the parent directories do not exist, they will be created as needed. + Argument | Type | Description | Default ---------|------|-------------|--------- path | `Path` | The path of the directory to create. | - permissions | `` | The permissions to set on the new directory. | `Int32(0o755)` +recursive | `` | If set to `yes`, then recursively create any parent directories if they don't exist, otherwise fail if the parent directory does not exist. When set to `yes`, this function behaves like `mkdir -p`. | `yes` **Return:** Nothing. diff --git a/api/paths.md b/api/paths.md index 07f0560b..4beabdc2 100644 --- a/api/paths.md +++ b/api/paths.md @@ -253,15 +253,17 @@ assert (./directory).children(include_hidden=yes) == [".git", "foo.txt"] ## Path.create_directory ```tomo -Path.create_directory : func(path: Path, permissions = Int32(0o755) -> Void) +Path.create_directory : func(path: Path, permissions = Int32(0o755), recursive = yes -> Void) ``` Creates a new directory at the specified path with the given permissions. If any of the parent directories do not exist, they will be created as needed. + Argument | Type | Description | Default ---------|------|-------------|--------- path | `Path` | The path of the directory to create. | - permissions | `` | The permissions to set on the new directory. | `Int32(0o755)` +recursive | `` | If set to `yes`, then recursively create any parent directories if they don't exist, otherwise fail if the parent directory does not exist. When set to `yes`, this function behaves like `mkdir -p`. | `yes` **Return:** Nothing. diff --git a/api/paths.yaml b/api/paths.yaml index 8fbd18dc..65d63671 100644 --- a/api/paths.yaml +++ b/api/paths.yaml @@ -258,6 +258,7 @@ Path.create_directory: description: > Creates a new directory at the specified path with the given permissions. If any of the parent directories do not exist, they will be created as needed. + note: > return: type: 'Void' description: > @@ -271,6 +272,12 @@ Path.create_directory: default: 'Int32(0o755)' description: > The permissions to set on the new directory. + recursive: + default: 'yes' + description: > + If set to `yes`, then recursively create any parent directories if they + don't exist, otherwise fail if the parent directory does not exist. When + set to `yes`, this function behaves like `mkdir -p`. example: | (./new_directory).create_directory() -- cgit v1.2.3 From 8b897851facaa177e2346e0d97fcba7411dfc0aa Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Thu, 27 Nov 2025 12:35:52 -0500 Subject: Update `setenv()` to take an optional value, also bugfix for `setenv()` returning a value. --- api/api.md | 4 ++-- api/builtins.md | 4 ++-- api/builtins.yaml | 5 +++-- 3 files changed, 7 insertions(+), 6 deletions(-) (limited to 'api') diff --git a/api/api.md b/api/api.md index ec6ffb49..f52691d3 100644 --- a/api/api.md +++ b/api/api.md @@ -166,7 +166,7 @@ say("world!") ## setenv ```tomo -setenv : func(name: Text, value: Text -> Void) +setenv : func(name: Text, value: Text? -> Void) ``` Sets an environment variable. @@ -174,7 +174,7 @@ Sets an environment variable. Argument | Type | Description | Default ---------|------|-------------|--------- name | `Text` | The name of the environment variable to set. | - -value | `Text` | The new value of the environment variable. | - +value | `Text?` | The new value of the environment variable. If `none`, then the environment variable will be unset. | - **Return:** Nothing. diff --git a/api/builtins.md b/api/builtins.md index 6d042741..2ef14275 100644 --- a/api/builtins.md +++ b/api/builtins.md @@ -166,7 +166,7 @@ say("world!") ## setenv ```tomo -setenv : func(name: Text, value: Text -> Void) +setenv : func(name: Text, value: Text? -> Void) ``` Sets an environment variable. @@ -174,7 +174,7 @@ Sets an environment variable. Argument | Type | Description | Default ---------|------|-------------|--------- name | `Text` | The name of the environment variable to set. | - -value | `Text` | The new value of the environment variable. | - +value | `Text?` | The new value of the environment variable. If `none`, then the environment variable will be unset. | - **Return:** Nothing. diff --git a/api/builtins.yaml b/api/builtins.yaml index 764a1bd4..af7c9319 100644 --- a/api/builtins.yaml +++ b/api/builtins.yaml @@ -157,9 +157,10 @@ setenv: description: > The name of the environment variable to set. value: - type: 'Text' + type: 'Text?' description: > - The new value of the environment variable. + The new value of the environment variable. If `none`, then the + environment variable will be unset. example: | setenv("FOOBAR", "xyz") -- cgit v1.2.3 From 4d8aa867c7f4661167a4742fbdd865ed2449503e Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sun, 30 Nov 2025 14:12:01 -0500 Subject: Add `base` parameter to integer parsing functions --- api/api.md | 6 +++++- api/integers.md | 6 +++++- api/integers.yaml | 12 ++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) (limited to 'api') diff --git a/api/api.md b/api/api.md index f52691d3..6a7d218b 100644 --- a/api/api.md +++ b/api/api.md @@ -662,7 +662,7 @@ assert nums[] == [5, 6, 7, 8, 9, 10] ## Int.parse ```tomo -Int.parse : func(text: Text, remainder: &Text? = none -> Int?) +Int.parse : func(text: Text, base: Int? = none, remainder: &Text? = none -> Int?) ``` Converts a text representation of an integer into an integer. @@ -670,6 +670,7 @@ Converts a text representation of an integer into an integer. Argument | Type | Description | Default ---------|------|-------------|--------- text | `Text` | The text containing the integer. | - +base | `Int?` | The numeric base to use when parsing the integer. If unspecified, the integer's base will be inferred from the text prefix. After any "+" or "-" sign, if the text begins with "0x", the base will be assumed to be 16, "0o" will assume base 8, "0b" will assume base 2, otherwise the base will be assumed to be 10. | `none` remainder | `&Text?` | If non-none, this argument will be set to the remainder of the text after the matching part. If none, parsing will only succeed if the entire text matches. | `none` **Return:** The integer represented by the text. If the given text contains a value outside of the representable range or if the entire text can't be parsed as an integer, `none` will be returned. @@ -690,6 +691,9 @@ assert Int.parse("asdf") == none # Outside valid range: assert Int8.parse("9999999") == none +# Explicitly specifying base: +assert Int.parse("10", base=16) == 16 + ``` ## Int.prev_prime diff --git a/api/integers.md b/api/integers.md index 6af66b0d..ef3a6a60 100644 --- a/api/integers.md +++ b/api/integers.md @@ -255,7 +255,7 @@ assert nums[] == [5, 6, 7, 8, 9, 10] ## Int.parse ```tomo -Int.parse : func(text: Text, remainder: &Text? = none -> Int?) +Int.parse : func(text: Text, base: Int? = none, remainder: &Text? = none -> Int?) ``` Converts a text representation of an integer into an integer. @@ -263,6 +263,7 @@ Converts a text representation of an integer into an integer. Argument | Type | Description | Default ---------|------|-------------|--------- text | `Text` | The text containing the integer. | - +base | `Int?` | The numeric base to use when parsing the integer. If unspecified, the integer's base will be inferred from the text prefix. After any "+" or "-" sign, if the text begins with "0x", the base will be assumed to be 16, "0o" will assume base 8, "0b" will assume base 2, otherwise the base will be assumed to be 10. | `none` remainder | `&Text?` | If non-none, this argument will be set to the remainder of the text after the matching part. If none, parsing will only succeed if the entire text matches. | `none` **Return:** The integer represented by the text. If the given text contains a value outside of the representable range or if the entire text can't be parsed as an integer, `none` will be returned. @@ -283,6 +284,9 @@ assert Int.parse("asdf") == none # Outside valid range: assert Int8.parse("9999999") == none +# Explicitly specifying base: +assert Int.parse("10", base=16) == 16 + ``` ## Int.prev_prime diff --git a/api/integers.yaml b/api/integers.yaml index 70709b04..b3c6b579 100644 --- a/api/integers.yaml +++ b/api/integers.yaml @@ -280,6 +280,15 @@ Int.parse: type: 'Text' description: > The text containing the integer. + base: + type: 'Int?' + default: 'none' + description: > + The numeric base to use when parsing the integer. If unspecified, the + integer's base will be inferred from the text prefix. After any "+" or + "-" sign, if the text begins with "0x", the base will be assumed to be + 16, "0o" will assume base 8, "0b" will assume base 2, otherwise the + base will be assumed to be 10. remainder: type: '&Text?' default: 'none' @@ -300,6 +309,9 @@ Int.parse: # Outside valid range: assert Int8.parse("9999999") == none + # Explicitly specifying base: + assert Int.parse("10", base=16) == 16 + Int.prev_prime: short: get the previous prime description: > -- cgit v1.2.3 From 19c8450aa0a9ea008a3e5fd4ec44f7c3761db663 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sun, 7 Dec 2025 22:53:45 -0500 Subject: Switch paths to use Result return values instead of fail() --- api/api.md | 41 +++++++++++++++++++++-------------------- api/paths.md | 41 +++++++++++++++++++++-------------------- api/paths.yaml | 41 +++++++++++++++++++++-------------------- 3 files changed, 63 insertions(+), 60 deletions(-) (limited to 'api') diff --git a/api/api.md b/api/api.md index 6a7d218b..2be5e4e9 100644 --- a/api/api.md +++ b/api/api.md @@ -2556,7 +2556,7 @@ assert (./not-a-file).accessed() == none ## Path.append ```tomo -Path.append : func(path: Path, text: Text, permissions: Int32 = Int32(0o644) -> Void) +Path.append : func(path: Path, text: Text, permissions: Int32 = Int32(0o644) -> Result) ``` Appends the given text to the file at the specified path, creating the file if it doesn't already exist. Failure to write will result in a runtime error. @@ -2567,18 +2567,18 @@ path | `Path` | The path of the file to append to. | - text | `Text` | The text to append to the file. | - permissions | `Int32` | The permissions to set on the file if it is being created. | `Int32(0o644)` -**Return:** Nothing. +**Return:** Either `Success` or `Failure(reason)`. **Example:** ```tomo -(./log.txt).append("extra line$(\n)") +(./log.txt).append("extra line\n")! ``` ## Path.append_bytes ```tomo -Path.append_bytes : func(path: Path, bytes: [Byte], permissions: Int32 = Int32(0o644) -> Void) +Path.append_bytes : func(path: Path, bytes: [Byte], permissions: Int32 = Int32(0o644) -> Result) ``` Appends the given bytes to the file at the specified path, creating the file if it doesn't already exist. Failure to write will result in a runtime error. @@ -2589,12 +2589,12 @@ path | `Path` | The path of the file to append to. | - bytes | `[Byte]` | The bytes to append to the file. | - permissions | `Int32` | The permissions to set on the file if it is being created. | `Int32(0o644)` -**Return:** Nothing. +**Return:** Either `Success` or `Failure(reason)`. **Example:** ```tomo -(./log.txt).append_bytes([104, 105]) +(./log.txt).append_bytes([104, 105])! ``` ## Path.base_name @@ -2781,7 +2781,7 @@ assert (./directory).children(include_hidden=yes) == [".git", "foo.txt"] ## Path.create_directory ```tomo -Path.create_directory : func(path: Path, permissions = Int32(0o755), recursive = yes -> Void) +Path.create_directory : func(path: Path, permissions = Int32(0o755), recursive = yes -> Result) ``` Creates a new directory at the specified path with the given permissions. If any of the parent directories do not exist, they will be created as needed. @@ -2793,7 +2793,7 @@ path | `Path` | The path of the directory to create. | - permissions | `` | The permissions to set on the new directory. | `Int32(0o755)` recursive | `` | If set to `yes`, then recursively create any parent directories if they don't exist, otherwise fail if the parent directory does not exist. When set to `yes`, this function behaves like `mkdir -p`. | `yes` -**Return:** Nothing. +**Return:** Either `Success` or `Failure(reason)`. **Example:** @@ -3159,7 +3159,7 @@ assert (/non/existent/file).owner() == none ## Path.parent ```tomo -Path.parent : func(path: Path -> Path) +Path.parent : func(path: Path -> Path?) ``` Returns the parent directory of the file or directory at the specified path. @@ -3168,7 +3168,7 @@ Argument | Type | Description | Default ---------|------|-------------|--------- path | `Path` | The path of the file or directory. | - -**Return:** The path of the parent directory. +**Return:** The path of the parent directory or `none` if the path is `(/)` (the file root). **Example:** @@ -3232,18 +3232,19 @@ Argument | Type | Description | Default path | `Path` | The path to convert. | - relative_to | `` | The base path for the relative path. | `(./)` -**Return:** The relative path. +**Return:** A relative path from the reference point to the given path. **Example:** ```tomo -assert (./path/to/file.txt).relative(relative_to=(./path)) == (./to/file.txt) +assert (./path/to/file.txt).relative_to((./path)) == (./to/file.txt) +assert (/tmp/foo).relative_to((/tmp)) == (./foo) ``` ## Path.remove ```tomo -Path.remove : func(path: Path, ignore_missing = no -> Void) +Path.remove : func(path: Path, ignore_missing = no -> Result) ``` Removes the file or directory at the specified path. A runtime error is raised if something goes wrong. @@ -3253,7 +3254,7 @@ Argument | Type | Description | Default path | `Path` | The path to remove. | - ignore_missing | `` | Whether to ignore errors if the file or directory does not exist. | `no` -**Return:** Nothing. +**Return:** Either `Success` or `Failure(reason)`. **Example:** @@ -3286,7 +3287,7 @@ assert (./path/to/file.txt).resolved(relative_to=(/foo)) == (/foo/path/to/file.t ## Path.set_owner ```tomo -Path.set_owner : func(path: Path, owner: Text? = none, group: Text? = none, follow_symlinks: Bool = yes -> Void) +Path.set_owner : func(path: Path, owner: Text? = none, group: Text? = none, follow_symlinks: Bool = yes -> Result) ``` Set the owning user and/or group for a path. @@ -3298,7 +3299,7 @@ owner | `Text?` | If non-none, the new user to assign to be the owner of the fil group | `Text?` | If non-none, the new group to assign to be the owner of the file. | `none` follow_symlinks | `Bool` | Whether to follow symbolic links. | `yes` -**Return:** Nothing. If a path does not exist, a failure will be raised. +**Return:** Either `Success` or `Failure(reason)`. **Example:** @@ -3374,7 +3375,7 @@ created.remove() ## Path.write ```tomo -Path.write : func(path: Path, text: Text, permissions = Int32(0o644) -> Void) +Path.write : func(path: Path, text: Text, permissions = Int32(0o644) -> Result) ``` Writes the given text to the file at the specified path, creating the file if it doesn't already exist. Sets the file permissions as specified. If the file writing cannot be successfully completed, a runtime error is raised. @@ -3385,7 +3386,7 @@ path | `Path` | The path of the file to write to. | - text | `Text` | The text to write to the file. | - permissions | `` | The permissions to set on the file if it is created. | `Int32(0o644)` -**Return:** Nothing. +**Return:** Either `Success` or `Failure(reason)`. **Example:** @@ -3396,7 +3397,7 @@ permissions | `` | The permissions to set on the file if it is created. | `Int3 ## Path.write_bytes ```tomo -Path.write_bytes : func(path: Path, bytes: [Byte], permissions = Int32(0o644) -> Void) +Path.write_bytes : func(path: Path, bytes: [Byte], permissions = Int32(0o644) -> Result) ``` Writes the given bytes to the file at the specified path, creating the file if it doesn't already exist. Sets the file permissions as specified. If the file writing cannot be successfully completed, a runtime error is raised. @@ -3407,7 +3408,7 @@ path | `Path` | The path of the file to write to. | - bytes | `[Byte]` | A list of bytes to write to the file. | - permissions | `` | The permissions to set on the file if it is created. | `Int32(0o644)` -**Return:** Nothing. +**Return:** Either `Success` or `Failure(reason)`. **Example:** diff --git a/api/paths.md b/api/paths.md index 4beabdc2..435932e3 100644 --- a/api/paths.md +++ b/api/paths.md @@ -28,7 +28,7 @@ assert (./not-a-file).accessed() == none ## Path.append ```tomo -Path.append : func(path: Path, text: Text, permissions: Int32 = Int32(0o644) -> Void) +Path.append : func(path: Path, text: Text, permissions: Int32 = Int32(0o644) -> Result) ``` Appends the given text to the file at the specified path, creating the file if it doesn't already exist. Failure to write will result in a runtime error. @@ -39,18 +39,18 @@ path | `Path` | The path of the file to append to. | - text | `Text` | The text to append to the file. | - permissions | `Int32` | The permissions to set on the file if it is being created. | `Int32(0o644)` -**Return:** Nothing. +**Return:** Either `Success` or `Failure(reason)`. **Example:** ```tomo -(./log.txt).append("extra line$(\n)") +(./log.txt).append("extra line\n")! ``` ## Path.append_bytes ```tomo -Path.append_bytes : func(path: Path, bytes: [Byte], permissions: Int32 = Int32(0o644) -> Void) +Path.append_bytes : func(path: Path, bytes: [Byte], permissions: Int32 = Int32(0o644) -> Result) ``` Appends the given bytes to the file at the specified path, creating the file if it doesn't already exist. Failure to write will result in a runtime error. @@ -61,12 +61,12 @@ path | `Path` | The path of the file to append to. | - bytes | `[Byte]` | The bytes to append to the file. | - permissions | `Int32` | The permissions to set on the file if it is being created. | `Int32(0o644)` -**Return:** Nothing. +**Return:** Either `Success` or `Failure(reason)`. **Example:** ```tomo -(./log.txt).append_bytes([104, 105]) +(./log.txt).append_bytes([104, 105])! ``` ## Path.base_name @@ -253,7 +253,7 @@ assert (./directory).children(include_hidden=yes) == [".git", "foo.txt"] ## Path.create_directory ```tomo -Path.create_directory : func(path: Path, permissions = Int32(0o755), recursive = yes -> Void) +Path.create_directory : func(path: Path, permissions = Int32(0o755), recursive = yes -> Result) ``` Creates a new directory at the specified path with the given permissions. If any of the parent directories do not exist, they will be created as needed. @@ -265,7 +265,7 @@ path | `Path` | The path of the directory to create. | - permissions | `` | The permissions to set on the new directory. | `Int32(0o755)` recursive | `` | If set to `yes`, then recursively create any parent directories if they don't exist, otherwise fail if the parent directory does not exist. When set to `yes`, this function behaves like `mkdir -p`. | `yes` -**Return:** Nothing. +**Return:** Either `Success` or `Failure(reason)`. **Example:** @@ -631,7 +631,7 @@ assert (/non/existent/file).owner() == none ## Path.parent ```tomo -Path.parent : func(path: Path -> Path) +Path.parent : func(path: Path -> Path?) ``` Returns the parent directory of the file or directory at the specified path. @@ -640,7 +640,7 @@ Argument | Type | Description | Default ---------|------|-------------|--------- path | `Path` | The path of the file or directory. | - -**Return:** The path of the parent directory. +**Return:** The path of the parent directory or `none` if the path is `(/)` (the file root). **Example:** @@ -704,18 +704,19 @@ Argument | Type | Description | Default path | `Path` | The path to convert. | - relative_to | `` | The base path for the relative path. | `(./)` -**Return:** The relative path. +**Return:** A relative path from the reference point to the given path. **Example:** ```tomo -assert (./path/to/file.txt).relative(relative_to=(./path)) == (./to/file.txt) +assert (./path/to/file.txt).relative_to((./path)) == (./to/file.txt) +assert (/tmp/foo).relative_to((/tmp)) == (./foo) ``` ## Path.remove ```tomo -Path.remove : func(path: Path, ignore_missing = no -> Void) +Path.remove : func(path: Path, ignore_missing = no -> Result) ``` Removes the file or directory at the specified path. A runtime error is raised if something goes wrong. @@ -725,7 +726,7 @@ Argument | Type | Description | Default path | `Path` | The path to remove. | - ignore_missing | `` | Whether to ignore errors if the file or directory does not exist. | `no` -**Return:** Nothing. +**Return:** Either `Success` or `Failure(reason)`. **Example:** @@ -758,7 +759,7 @@ assert (./path/to/file.txt).resolved(relative_to=(/foo)) == (/foo/path/to/file.t ## Path.set_owner ```tomo -Path.set_owner : func(path: Path, owner: Text? = none, group: Text? = none, follow_symlinks: Bool = yes -> Void) +Path.set_owner : func(path: Path, owner: Text? = none, group: Text? = none, follow_symlinks: Bool = yes -> Result) ``` Set the owning user and/or group for a path. @@ -770,7 +771,7 @@ owner | `Text?` | If non-none, the new user to assign to be the owner of the fil group | `Text?` | If non-none, the new group to assign to be the owner of the file. | `none` follow_symlinks | `Bool` | Whether to follow symbolic links. | `yes` -**Return:** Nothing. If a path does not exist, a failure will be raised. +**Return:** Either `Success` or `Failure(reason)`. **Example:** @@ -846,7 +847,7 @@ created.remove() ## Path.write ```tomo -Path.write : func(path: Path, text: Text, permissions = Int32(0o644) -> Void) +Path.write : func(path: Path, text: Text, permissions = Int32(0o644) -> Result) ``` Writes the given text to the file at the specified path, creating the file if it doesn't already exist. Sets the file permissions as specified. If the file writing cannot be successfully completed, a runtime error is raised. @@ -857,7 +858,7 @@ path | `Path` | The path of the file to write to. | - text | `Text` | The text to write to the file. | - permissions | `` | The permissions to set on the file if it is created. | `Int32(0o644)` -**Return:** Nothing. +**Return:** Either `Success` or `Failure(reason)`. **Example:** @@ -868,7 +869,7 @@ permissions | `` | The permissions to set on the file if it is created. | `Int3 ## Path.write_bytes ```tomo -Path.write_bytes : func(path: Path, bytes: [Byte], permissions = Int32(0o644) -> Void) +Path.write_bytes : func(path: Path, bytes: [Byte], permissions = Int32(0o644) -> Result) ``` Writes the given bytes to the file at the specified path, creating the file if it doesn't already exist. Sets the file permissions as specified. If the file writing cannot be successfully completed, a runtime error is raised. @@ -879,7 +880,7 @@ path | `Path` | The path of the file to write to. | - bytes | `[Byte]` | A list of bytes to write to the file. | - permissions | `` | The permissions to set on the file if it is created. | `Int32(0o644)` -**Return:** Nothing. +**Return:** Either `Success` or `Failure(reason)`. **Example:** diff --git a/api/paths.yaml b/api/paths.yaml index 65d63671..02b8fbe8 100644 --- a/api/paths.yaml +++ b/api/paths.yaml @@ -27,9 +27,9 @@ Path.append: Appends the given text to the file at the specified path, creating the file if it doesn't already exist. Failure to write will result in a runtime error. return: - type: 'Void' + type: 'Result' description: > - Nothing. + Either `Success` or `Failure(reason)`. args: path: type: 'Path' @@ -45,7 +45,7 @@ Path.append: description: > The permissions to set on the file if it is being created. example: | - (./log.txt).append("extra line$(\n)") + (./log.txt).append("extra line\n")! Path.append_bytes: short: append bytes to a file @@ -53,9 +53,9 @@ Path.append_bytes: Appends the given bytes to the file at the specified path, creating the file if it doesn't already exist. Failure to write will result in a runtime error. return: - type: 'Void' + type: 'Result' description: > - Nothing. + Either `Success` or `Failure(reason)`. args: path: type: 'Path' @@ -71,7 +71,7 @@ Path.append_bytes: description: > The permissions to set on the file if it is being created. example: | - (./log.txt).append_bytes([104, 105]) + (./log.txt).append_bytes([104, 105])! Path.base_name: short: base name of a file @@ -260,9 +260,9 @@ Path.create_directory: any of the parent directories do not exist, they will be created as needed. note: > return: - type: 'Void' + type: 'Result' description: > - Nothing. + Either `Success` or `Failure(reason)`. args: path: type: 'Path' @@ -604,9 +604,9 @@ Path.parent: description: > Returns the parent directory of the file or directory at the specified path. return: - type: 'Path' + type: 'Path?' description: > - The path of the parent directory. + The path of the parent directory or `none` if the path is `(/)` (the file root). args: path: type: 'Path' @@ -666,7 +666,7 @@ Path.relative_to: return: type: 'Path' description: > - The relative path. + A relative path from the reference point to the given path. args: path: type: 'Path' @@ -677,16 +677,17 @@ Path.relative_to: description: > The base path for the relative path. example: | - assert (./path/to/file.txt).relative(relative_to=(./path)) == (./to/file.txt) + assert (./path/to/file.txt).relative_to((./path)) == (./to/file.txt) + assert (/tmp/foo).relative_to((/tmp)) == (./foo) Path.remove: short: remove a file or directory description: > Removes the file or directory at the specified path. A runtime error is raised if something goes wrong. return: - type: 'Void' + type: 'Result' description: > - Nothing. + Either `Success` or `Failure(reason)`. args: path: type: 'Path' @@ -725,9 +726,9 @@ Path.set_owner: description: > Set the owning user and/or group for a path. return: - type: 'Void' + type: 'Result' description: > - Nothing. If a path does not exist, a failure will be raised. + Either `Success` or `Failure(reason)`. args: path: type: 'Path' @@ -818,9 +819,9 @@ Path.write: it doesn't already exist. Sets the file permissions as specified. If the file writing cannot be successfully completed, a runtime error is raised. return: - type: 'Void' + type: 'Result' description: > - Nothing. + Either `Success` or `Failure(reason)`. args: path: type: 'Path' @@ -844,9 +845,9 @@ Path.write_bytes: it doesn't already exist. Sets the file permissions as specified. If the file writing cannot be successfully completed, a runtime error is raised. return: - type: 'Void' + type: 'Result' description: > - Nothing. + Either `Success` or `Failure(reason)`. args: path: type: 'Path' -- cgit v1.2.3