Skip to content
Topaz6.0 · Before release
Download

Search documentation

Specification 6.0 · Not released · Tested product 5.21.3

Use arrow keys to choose a result. Press Enter to open.

Type an API name, diagnostic number, rule, or project topic.

    Library · std.path

    Path.extension

    Returns the optional extension of this path.

    extension() -> Option<string>
    Module
    std.path
    Receiver
    Path
    Minimum arity
    0
    Maximum arity
    0

    Declaration and parameters

    Link

    Availability

    Included by default: Pending

    Import std.path in language mode 5.21.

    The current compiler selects std/path.tpz for this language mode. Availability in other released editions and inclusion in each installed distribution are Pending.

    Source evidence

    Receiver

    Path

    Parameter constraints

    A Path is immutable normalized relative text. Every member evaluates its receiver and arguments once in ordinary call order. Members perform no host access and leave the receiver unchanged on success and failure.

    toString returns the exact normalized representation. Separators are forward slashes and the relative root is a dot. Constructing a Path from that text returns the same representation.

    join accepts nonempty relative child text. It rejects NUL, a leading separator, and a colon immediately after one ASCII character before combining the child with the receiver. Both slash forms are separators. Parent components remove preceding components from the combined path and return Err when none remain to remove.

    Joining a child may reach the relative root but may not cross it. A dot child preserves the receiver. Invalid child text returns Err containing an error string without producing a Path. Error text identifies Path.join and the invalid condition.

    parent removes the final component. For a one component path it returns Some containing the dot root. The relative root has no parent and returns None().

    fileName returns the final component without any preceding separator. The relative root returns None(). These results describe text and do not establish whether the path identifies a file or directory.

    extension returns the text after the final dot in the file name, provided that dot is not its first character. A leading dot alone does not introduce an extension. A final dot returns Some(""). A name without such a dot and the relative root return None().

    withExtension replaces the final extension or appends one when it is absent. The argument supplies the suffix without a leading dot. An empty argument removes an existing suffix and its separating dot. A leading dot, either separator, or NUL in the argument returns Err.

    withExtension preserves a leading dot that belongs to the file name. It returns Err when the receiver is the relative root because that path has no file name. A successful replacement is normalized with the same rules as Path.from.

    Path validation describes lexical text. Host operations may reject an otherwise valid Path because of platform naming rules, permissions, or capability restrictions. A Path does not establish filesystem existence or prevent a symbolic link from resolving elsewhere.

    Result

    The declared result type is Option<string>.

    Effects

    Failures

    Result and effects

    Link

    Return the suffix after the final nonleading dot in the file name. A final dot gives a present empty suffix.

    Related entries

    Link

    std.path

    Inspect and transform normalized paths

    Link
    Ruletopaz.stdlib.contract.path-operations.rule

    Inspect and transform normalized paths

    A Path is immutable normalized relative text. Every member evaluates its receiver and arguments once in ordinary call order. Members perform no host access and leave the receiver unchanged on success and failure.

    toString returns the exact normalized representation. Separators are forward slashes and the relative root is a dot. Constructing a Path from that text returns the same representation.

    join accepts nonempty relative child text. It rejects NUL, a leading separator, and a colon immediately after one ASCII character before combining the child with the receiver. Both slash forms are separators. Parent components remove preceding components from the combined path and return Err when none remain to remove.

    Joining a child may reach the relative root but may not cross it. A dot child preserves the receiver. Invalid child text returns Err containing an error string without producing a Path. Error text identifies Path.join and the invalid condition.

    parent removes the final component. For a one component path it returns Some containing the dot root. The relative root has no parent and returns None().

    fileName returns the final component without any preceding separator. The relative root returns None(). These results describe text and do not establish whether the path identifies a file or directory.

    extension returns the text after the final dot in the file name, provided that dot is not its first character. A leading dot alone does not introduce an extension. A final dot returns Some(""). A name without such a dot and the relative root return None().

    withExtension replaces the final extension or appends one when it is absent. The argument supplies the suffix without a leading dot. An empty argument removes an existing suffix and its separating dot. A leading dot, either separator, or NUL in the argument returns Err.

    withExtension preserves a leading dot that belongs to the file name. It returns Err when the receiver is the relative root because that path has no file name. A successful replacement is normalized with the same rules as Path.from.

    Path validation describes lexical text. Host operations may reject an otherwise valid Path because of platform naming rules, permissions, or capability restrictions. A Path does not establish filesystem existence or prevent a symbolic link from resolving elsewhere.

    Why

    One normalized representation makes composition predictable. Parent and extension queries describe components without consulting host state. A suffix has one accepted spelling, and joining validates the child before its leading separator can disappear inside the combined text.

    Source evidence

    Join relative components without changing the receiver

    Link
    main.tpzJoin relative components without changing the receiverOpen in Playground
    1. import std.path { Path }
    2. import std.test
    3. import std.io
    4. let base = test.assertOk(Path.from("chapters/draft"))
    5. let child = test.assertOk(base.join("../final/./main.tpz"))
    6. io.writeLine(base.toString())
    7. io.writeLine(child.toString())
    8. io.writeLine(test.assertOk(base.join("../..")).toString())
    9. io.writeLine(test.assertOk(base.join(".")).toString())
    Expected outputexit 0
    chapters/draft
    chapters/final/main.tpz
    .
    chapters/draft
    
    $ topaz run main.tpz · target product 5.21.3
    Expected result

    Expected result

    Execution completes. Exit code 0.

    Expected stdout
    1. chapters/draft
    2. chapters/final/main.tpz
    3. .
    4. chapters/draft
    Source evidence

    Reject invalid child text before joining

    Link
    main.tpzReject invalid child text before joiningOpen in Playground
    1. import std.path { Path }
    2. import std.test
    3. import std.io
    4. let base = test.assertOk(Path.from("chapters"))
    5. for child in (["", "/outside", "C:/outside", "../../outside"]) {
    6. match (base.join(child)) {
    7. case Err(_) => io.writeLine("rejected")
    8. case Ok(_) => io.writeLine("accepted")
    9. }
    10. }
    11. io.writeLine(base.toString())
    Expected outputexit 0
    rejected
    rejected
    rejected
    rejected
    chapters
    
    $ topaz run main.tpz · target product 5.21.3
    Expected result

    Expected result

    Execution completes. Exit code 0.

    Expected stdout
    1. rejected
    2. rejected
    3. rejected
    4. rejected
    5. chapters
    Source evidence

    Inspect the final component and the relative root

    Link
    main.tpzInspect the final component and the relative rootOpen in Playground
    1. import std.path { Path }
    2. import std.test
    3. import std.io
    4. let file = test.assertOk(Path.from("chapters/main.tpz"))
    5. io.writeLine(test.assertSome(file.parent()).toString())
    6. io.writeLine(test.assertSome(file.fileName()))
    7. io.writeLine(test.assertSome(file.extension()))
    8. let root = test.assertOk(Path.from("."))
    9. test.assertNone(root.parent())
    10. test.assertNone(root.fileName())
    11. test.assertNone(root.extension())
    12. io.writeLine(root.toString())
    Expected outputexit 0
    chapters
    main.tpz
    tpz
    .
    
    $ topaz run main.tpz · target product 5.21.3
    Expected result

    Expected result

    Execution completes. Exit code 0.

    Expected stdout
    1. chapters
    2. main.tpz
    3. tpz
    4. .
    Source evidence

    Keep the relative root as the parent of one component

    Link
    main.tpzKeep the relative root as the parent of one componentOpen in Playground
    1. import std.path { Path }
    2. import std.test
    3. import std.io
    4. let file = test.assertOk(Path.from("main.tpz"))
    5. match (file.parent()) {
    6. case Some(parent) => io.writeLine(parent.toString())
    7. case None() => io.writeLine("missing")
    8. }
    Expected outputexit 0
    .
    
    $ topaz run main.tpz · target product 5.21.3
    Expected result

    Expected result

    Execution completes. Exit code 0.

    Expected stdout
    1. .
    Source evidence

    Distinguish an absent extension from an empty extension

    Link
    main.tpzDistinguish an absent extension from an empty extensionOpen in Playground
    1. import std.path { Path }
    2. import std.test
    3. import std.io
    4. for name in (["README", ".env", ".env.local", "archive.tar.gz", "trailing."]) {
    5. let file = test.assertOk(Path.from(name))
    6. match (file.extension()) {
    7. case Some(extension) => io.writeLine("present [{extension}]")
    8. case None() => io.writeLine("absent")
    9. }
    10. }
    Expected outputexit 0
    absent
    absent
    present [local]
    present [gz]
    present []
    
    $ topaz run main.tpz · target product 5.21.3
    Expected result

    Expected result

    Execution completes. Exit code 0.

    Expected stdout
    1. absent
    2. absent
    3. present [local]
    4. present [gz]
    5. present []
    Source evidence

    Replace and remove a final extension

    Link
    main.tpzReplace and remove a final extensionOpen in Playground
    1. import std.path { Path }
    2. import std.test
    3. import std.io
    4. let file = test.assertOk(Path.from("chapters/main.tpz"))
    5. io.writeLine(test.assertOk(file.withExtension("pdf")).toString())
    6. io.writeLine(test.assertOk(file.withExtension("")).toString())
    7. io.writeLine(file.toString())
    Expected outputexit 0
    chapters/main.pdf
    chapters/main
    chapters/main.tpz
    
    $ topaz run main.tpz · target product 5.21.3
    Expected result

    Expected result

    Execution completes. Exit code 0.

    Expected stdout
    1. chapters/main.pdf
    2. chapters/main
    3. chapters/main.tpz
    Source evidence

    Preserve the name of a file that starts with a dot

    Link
    main.tpzPreserve the name of a file that starts with a dotOpen in Playground
    1. import std.path { Path }
    2. import std.test
    3. import std.io
    4. let file = test.assertOk(Path.from(".env"))
    5. io.writeLine(test.assertOk(file.withExtension("local")).toString())
    6. io.writeLine(test.assertOk(file.withExtension("")).toString())
    Expected outputexit 0
    .env.local
    .env
    
    $ topaz run main.tpz · target product 5.21.3
    Expected result

    Expected result

    Execution completes. Exit code 0.

    Expected stdout
    1. .env.local
    2. .env
    Source evidence

    Reject a second suffix spelling and a path without a file name

    Link
    main.tpzReject a second suffix spelling and a path without a file nameOpen in Playground
    1. import std.path { Path }
    2. import std.test
    3. import std.io
    4. let file = test.assertOk(Path.from("chapter.txt"))
    5. for extension in ([".pdf", "pdf/extra", "pdf\\extra"]) {
    6. match (file.withExtension(extension)) {
    7. case Err(_) => io.writeLine("rejected")
    8. case Ok(_) => io.writeLine("accepted")
    9. }
    10. }
    11. let root = test.assertOk(Path.from("."))
    12. match (root.withExtension("pdf")) {
    13. case Err(_) => io.writeLine("root rejected")
    14. case Ok(_) => io.writeLine("root accepted")
    15. }
    Expected outputexit 0
    rejected
    rejected
    rejected
    root rejected
    
    $ topaz run main.tpz · target product 5.21.3
    Expected result

    Expected result

    Execution completes. Exit code 0.

    Expected stdout
    1. rejected
    2. rejected
    3. rejected
    4. root rejected
    Source evidence

    Menu

    Download