OsStr

:= [
    Utf8(Str),
    UnixBytes(List(U8)),
    WindowsU16s(List(U16)),
]

Represent operating-system strings without losing non-Unicode data.

Native Unix bytes and Windows UTF-16 units roundtrip through host effects; use display only when a lossy representation is acceptable.

from_str : Str -> OsStr

Create an OS string from a dynamic UTF-8 Str. String literals can be used directly wherever an OsStr is expected. The host lowers UTF-8 text to the active OS representation.

utf8 : Str -> OsStr

Create a UTF-8 OS string from a dynamic Str. The same as from_str, named like the other representation constructors.

unix : Str -> OsStr

Create a Unix OS string from a Roc string by storing its UTF-8 bytes.

unix_bytes : List(U8) -> OsStr

Create a Unix OS string from raw bytes without validating UTF-8.

windows : Str -> OsStr

Create a Windows OS string from a Roc string by storing its UTF-16 code units.

from_quote : Str -> Try(OsStr, [BadQuotedBytes(Str)])

Build an OS string from a quoted string literal.

parser_for : _

Parse and encode every OS string representation as a lossless tagged value.

to_str_try : OsStr -> Try(Str, [InvalidStr(U64)])

Convert an OS string to a string if its raw representation is valid text.

to_bytes : OsStr -> List(U8)

Convert an OS string to the bytes that represent it, for writing to a byte stream such as [Stdout.write_bytes!] or [Stderr.write_bytes!].

UTF-8 text and Unix OS strings return their exact bytes, so non-Unicode Unix data is preserved. Windows OS strings are UTF-16 code units rather than bytes, so they are encoded as UTF-8 with unpaired surrogates replaced by U+FFFD; that conversion is lossy and must not be used for roundtripping.

display : OsStr -> Str

Convert an OS string to a best-effort display string, replacing invalid text with U+FFFD. This representation is lossy and must not be used for roundtripping.

to_inspect : OsStr -> Str

Customize debug output for Str.inspect.

is_eq : OsStr, OsStr -> Bool

Compare OS strings by content, whichever representation holds it.

A string literal is stored as UTF-8, while the operating system hands back native units, so args.contains("--verbose") and Env.var!("EDITOR")? == "vim" compare text with native units.

  • Two values that are valid Unicode are equal when they are the same text, in any mix of UTF-8, Unix bytes and Windows UTF-16.
  • Unix bytes that are not valid UTF-8, or UTF-16 with an unpaired surrogate, equal only the identical units of the same kind, and never a UTF-8 value.

Nothing is normalized: case, Unicode normal forms and path separators all still distinguish two values.

to_hash : OsStr, Hasher -> Hasher

Hash OS strings consistently with is_eq: valid Unicode hashes as its text in every representation, and anything else as its raw units.

to_raw : OsStr -> [Utf8(Str), UnixBytes(List(U8)), WindowsU16s(List(U16))]

Expose the host ABI representation.

from_raw : [Utf8(Str), UnixBytes(List(U8)), WindowsU16s(List(U16))] -> OsStr

Build an OS string from the host ABI representation.