package configkit import ( "io" "io/fs" "gitea.maximumdirect.net/eric/ConfigKit/internal/engine" ) // Source is an opaque configuration input. Construct sources with File, // Filesystem.File, SearchConfig, Bytes, Reader, Mapping, or NoSource; the zero // value is invalid. SearchConfig selects a host file when a load consumes it. type Source struct{ value engine.Source } // Filesystem is a reusable opaque namespace for a caller-owned fs.FS. Copies // preserve identity; separately constructed values are distinct even if their // labels or underlying filesystems match. The filesystem is never closed. type Filesystem struct{ value engine.Filesystem } // NewFilesystem borrows filesystem without opening it. Label must be nonempty // and safe to display; a nil filesystem or invalid label is reported when a // source from the returned namespace is consumed. func NewFilesystem(label string, filesystem fs.FS) Filesystem { return Filesystem{value: engine.NewFilesystem(label, filesystem)} } // File selects a non-root fs.ValidPath name in this filesystem. Each load // reopens the file; constructor problems are reported when the source is used. func (f Filesystem) File(name string) Source { return Source{value: f.value.File(name)} } // File returns a source that reopens path for every load attempt. func File(path string) Source { return Source{value: engine.File(path)} } // Bytes snapshots data immediately. Label must be nonempty and safe to display; // constructor problems are reported when the source is consumed. func Bytes(label string, data []byte) Source { return Source{value: engine.Bytes(label, data)} } // Reader returns a single-use source. ConfigKit consumes input but never closes it. // Copies of the returned Source share the same single-use claim. func Reader(label string, input io.Reader) Source { return Source{value: engine.Reader(label, input)} } // Mapping snapshots supported built-in values immediately. A nil root map is // invalid; an empty map is a valid empty document. Values may be nil, built-in // scalars, []any, or map[string]any recursively. Unsupported values and cycles // are reported when the source is consumed. Label must be nonempty and safe to // display. Later caller mutation cannot change the captured document. func Mapping(label string, values map[string]any) Source { return Source{value: engine.Mapping(label, values)} } // NoSource selects an absent input for defaults and resolution. It creates no // source record and has no main declarations to traverse when imports are enabled. // An active overlay requires explicit filesystem context. func NoSource() Source { return Source{value: engine.NoSource()} } func (s Source) toEngine() engine.Source { return s.value }