using AIStudio.Models.Matching; namespace AIStudio.Models; /// /// Collects the rules of one family as they are stated. /// /// /// The order rules are stated in changes nothing about which one wins -- that is what the computed /// specificity is for. It matters in one place only: a variant which inherits takes what the rule /// before it stated, so that a family can say what its models have in common once and then say /// only what makes each variant different. /// /// What the rules name as their origin, which is the family's name. public sealed class ModelFamilyBuilder(string origin) { private readonly List stated = []; /// /// States a rule which chooses the model. /// /// The name, or the part of it, this rule answers for. In normalized form. /// The rule, to go on stating. public ModelRuleBuilder Rule(string text) => this.Add(text, ModelRuleKind.SELECTOR); /// /// States a rule which adjusts whatever chose the model. /// /// The name, or the part of it, this rule answers for. In normalized form. /// The rule, to go on stating. public ModelRuleBuilder Modifier(string text) => this.Add(text, ModelRuleKind.MODIFIER); /// /// Turns everything stated into rules. /// /// The rules, in the order they were stated. internal IReadOnlyList Build() { var built = new List(this.stated.Count); var byPatternText = new Dictionary(StringComparer.Ordinal); ModelProfileChange? previous = null; foreach (var statement in this.stated) { var rule = statement.Build(statement.InheritanceBasis(byPatternText, previous)); built.Add(rule); byPatternText[rule.Pattern.Text] = rule.Change; previous = rule.Change; } return built; } private ModelRuleBuilder Add(string text, ModelRuleKind kind) { var statement = new ModelRuleBuilder(text, kind, origin); this.stated.Add(statement); return statement; } }