package configkit import "gitea.maximumdirect.net/eric/ConfigKit/internal/engine" // SequenceSelector identifies a sequence destination through literal mapping // keys and arbitrary mapping-key segments. A zero selector identifies the root. type SequenceSelector []SequenceSelectorSegment // SequenceSelectorSegment is one literal mapping key or wildcard mapping key. // Its zero value is the literal empty key. type SequenceSelectorSegment struct { key string anyMappingKey bool } // SequenceLiteralKey selects a literal mapping key, including an empty key or // the literal string "*". func SequenceLiteralKey(key string) SequenceSelectorSegment { return SequenceSelectorSegment{key: key} } // SequenceAnyMappingKey selects any single mapping key. func SequenceAnyMappingKey() SequenceSelectorSegment { return SequenceSelectorSegment{anyMappingKey: true} } // SequenceIdentity records the identity fields used for strict sequence // composition and identified-record parent lookup. It does not add final-result // identity validation; that check remains the application's responsibility. type SequenceIdentity struct { exactPath bool path Path selector SequenceSelector identityFields []string } // SequenceIdentityAt registers identity fields at an exact mapping path. The // path and fields are copied; invalid paths and empty field sets are reported // during load validation. func SequenceIdentityAt(path Path, fields ...string) SequenceIdentity { return SequenceIdentity{ exactPath: true, path: path.clone(), identityFields: append([]string(nil), fields...), } } // SequenceIdentityMatching registers identity fields at destinations matched by // selector. Literal and wildcard selector segments are copied. Empty field sets // are reported during load validation. func SequenceIdentityMatching(selector SequenceSelector, fields ...string) SequenceIdentity { return SequenceIdentity{ selector: append(SequenceSelector(nil), selector...), identityFields: append([]string(nil), fields...), } } func toEngineSequenceIdentity(identity SequenceIdentity) engine.SequenceIdentityRegistrationInput { registration := engine.SequenceIdentityRegistrationInput{ IdentityFields: append([]string(nil), identity.identityFields...), } if identity.exactPath { path := toEnginePath(identity.path.clone()) registration.ExactPath = &path return registration } registration.Selector = make([]engine.SequenceIdentitySelectorSegment, len(identity.selector)) for index, segment := range identity.selector { registration.Selector[index] = engine.SequenceIdentitySelectorSegment{ Key: segment.key, AnyMappingKey: segment.anyMappingKey, } } return registration }