Under heavy development. This site describes the intended 1.0 language. Current features and performance vary. Development status
Sn50SnThe SnAPI programming language
Development · Evolving reference

ExtendedAttributeWriteMode

Selects one native extended-attribute creation/update policy. These cases are semantic identities, not target flags. No implicit fallback turns CreateNew into replacement or ReplaceExisting into creation. Values own no resource and allocate nothing; ordinary shared mutation needs synchronization.

Sn is under heavy development. This reference includes the intended 1.0 design; features may be incomplete in the current compiler. Read the status →

Module std.fs

import std.fs;

Public declaration contracts and authored examples. A page can document several related symbols. Implementation bodies are excluded.

ExtendedAttributeWriteMode

pub enum ExtendedAttributeWriteMode

Selects one native extended-attribute creation/update policy. These cases are semantic identities, not target flags. No implicit fallback turns CreateNew into replacement or ReplaceExisting into creation. Values own no resource and allocate nothing; ordinary shared mutation needs synchronization.

Example

module example.file_attributes;
from std.process import ProgramInputs;
from std.fs import Path;
from std.collections import Vector;
from std.fs import File;
from std.io import IoError;
from std.prelude import Result;
fn ReplaceOwnedAttribute(Opened: mut File&) -> Result<void, IoError> {
    let Name: byte[13] = [0x75_byte, 0x73_byte, 0x65_byte, 0x72_byte, 0x2E_byte, 0x73_byte, 0x6E_byte, 0x2D_byte, 0x70_byte, 0x6C_byte, 0x61_byte, 0x6E_byte, 0x38_byte];
    let Bytes: byte[2] = [0_byte, 0xFF_byte];
    let Empty: byte[0] = [];
    // The caller reserves this name for this workflow and retains the file loan.
    switch Opened.RemoveExtendedAttribute(Name) {
        case .Ok => {}
        case .Err { Error = PatternPayload5032 } => {
            switch PatternPayload5032 {
                case .Failure { Reason = PatternPayload5033 } if (PatternPayload5033 is .NotFound) => {}
                default => { let Error = PatternPayload5032; return .Err { Error = Error }; }
            }
        }
    }
    let Missing = {
        var MissingResult = Opened.ReadExtendedAttribute(Name);
        switch MissingResult {
            case .Ok { Value = MissingPayload: mut Vector<byte>?& } => break move(MissingPayload);
            case .Err { Error = Error } => return .Err { Error = Error };
        }
    };
    if Missing is .Some { Value = _ } { return .Err { Error = .Failure { Reason = .NativeFailure, Transferred = 0 } }; }
    switch Opened.WriteExtendedAttribute(Name, Bytes, .CreateNew) { case .Ok => {} case .Err { Error = Error } => return .Err { Error = Error }; }
    var Read = {
        var ReadResult = Opened.ReadExtendedAttribute(Name);
        switch ReadResult {
            case .Ok { Value = ReadPayload: mut Vector<byte>?& } => break move(ReadPayload);
            case .Err { Error = Error } => return .Err { Error = Error };
        }
    };
    var Owned = {
        // Scoped writable carriers end immediately after explicit payload transfer.
        var OwnedCarrier = move(Read);
        switch OwnedCarrier {
            case .Some { Value = Value: mut Vector<byte>& } => break move(Value);
            case .None => return .Err { Error = .Failure { Reason = .NativeFailure, Transferred = 0 } };
        }
    };
    if Owned.Length != 2 || Owned[0] != 0_byte || Owned[1] != 0xFF_byte { return .Err { Error = .Failure { Reason = .NativeFailure, Transferred = 0 } }; }
    switch Opened.WriteExtendedAttribute(Name, Bytes, .CreateNew) {
        case .Err { Error = PatternPayload5034 } => {
            switch PatternPayload5034 {
                case .Failure { Reason = PatternPayload5035 } if (PatternPayload5035 is .AlreadyExists) => {}
                default => { let Error = PatternPayload5034; return .Err { Error = Error }; }
            }
        }
        case .Ok => return .Err { Error = .Failure { Reason = .NativeFailure, Transferred = 0 } };
    }
    switch Opened.WriteExtendedAttribute(Name, Empty, .ReplaceExisting) { case .Ok => {} case .Err { Error = Error } => return .Err { Error = Error }; }
    var Present = {
        var PresentResult = Opened.ReadExtendedAttribute(Name);
        switch PresentResult {
            case .Ok { Value = PresentPayload: mut Vector<byte>?& } => break move(PresentPayload);
            case .Err { Error = Error } => return .Err { Error = Error };
        }
    };
    switch move(Present) {
        case .Some { Value = Value } => { if Value.Length != 0 { return .Err { Error = .Failure { Reason = .NativeFailure, Transferred = 0 } }; } }
        case .None => return .Err { Error = .Failure { Reason = .NativeFailure, Transferred = 0 } };
    }
    // Upsert remains an explicit choice, even when the name already exists.
    switch Opened.WriteExtendedAttribute(Name, Bytes, .Upsert) { case .Ok => {} case .Err { Error = Error } => return .Err { Error = Error }; }
    var Names = {
        var NamesCreation = Opened.DiscoverExtendedAttributeNames();
        switch NamesCreation {
            case .Ok { Value = Value: mut Vector<Vector<byte>>& } => break move(Value);
            case .Err { Error = Error } => return .Err { Error = Error };
        }
    };
    var Found = false;
    for Candidate in Names.AsSlice() {
        if Candidate.Length == Name.Length {
            var Equal = true;
            var Index: usize = 0;
            while Index < Name.Length { if Candidate[Index] != Name[Index] { Equal = false; } Index += 1; }
            if Equal { Found = true; }
        }
    }
    if !Found { return .Err { Error = .Failure { Reason = .NativeFailure, Transferred = 0 } }; }
    return Opened.RemoveExtendedAttribute(Name);
}

// Supply absolute paths to exclusively owned, disposable fixtures as arguments.
fn Main(Inputs: ProgramInputs) -> i32 {
    if Inputs.Arguments().Length != 2 { return 20; }
    let OwnedPathText = switch Inputs.Arguments()[1].TryViewUtf8() { case .Some { Value = Text } => break Text; case .None => return 21; };
    var OwnedPath = {
        var Creation = Path.TryCreate(OwnedPathText);
        switch Creation { case .Ok { Value = Created: mut Path& } => break move(Created); case .Err => return 22; }
    };
    var Opened = {
        var Creation = File.TryOpen(OwnedPath.View, .ReadWrite);
        switch Creation { case .Ok { Value = Created: mut File& } => break move(Created); case .Err => return 23; }
    };
    let Outcome = ReplaceOwnedAttribute(Opened);
    // End every operation's receiver loan before closing the sole native owner.
    let Closed = Opened.Close();
    if Outcome is .Err { Error = _ } { return 27; }
    if Closed is .Err { Error = _ } { return 28; }
    return 0;
}

ExtendedAttributeWriteMode.Upsert

Upsert;

Creates or replaces the named value.

ExtendedAttributeWriteMode.CreateNew

CreateNew;

Creates only, failing AlreadyExists when present.

ExtendedAttributeWriteMode.ReplaceExisting

ReplaceExisting;

Replaces only, failing NotFound when absent.

Documentation snapshot: October 24, 2026 About versions ↗
Searching Development · language & standard library