public Parser AddVerb <T>(Action <T> handler) { // Recurse declaring types tagged with CategoryAttribute List <Type> lineage = GetCategoryLineage(typeof(T)); // Find deepest common category ancestor between T and root CategoryTree common = root; int i = 0; for (; i < lineage.Count; i++) { CategoryTree next = common.Find(lineage[i]); if (next == null) { break; } common = next; } // Create missing nodes in category tree for (; i < lineage.Count; i++) { CategoryTree node = new CategoryTree(lineage[i]); common.AddChild(node); common = node; } // Add verb to the deepest category common.AddVerbNode(new VerbNode(typeof(T))); return(this); }
public void Process(string[] args) { // Find deepest matching category CategoryTree catNode = root; int i = 0; for (; i < args.Length; i++) { CategoryTree child = catNode.Children .FirstOrDefault(c => c.Matches(args[i])); if (child == null) { break; } catNode = child; } // Find matching verb in category VerbNode verbNode = catNode.VerbNodes .First(v => v.Matches(args[i])); i++; // Remove categories and verb from argument list args = args.Slice(i); // Construct result verb object object verbObj = Activator.CreateInstance(verbNode.Type); while (true) { (int oi, string name) = FindLongOption(args); if (oi == -1) { break; } OptionNode optionNode = verbNode.OptionNodes .First(o => o.Matches(name)); if (optionNode.IsFlag) { // Remove option from args (string _, string[] rest) = RemoveLongOption(args, oi, false); args = rest; optionNode.SetValue(verbObj, true); } else { // Remove option from args (string arg, string[] rest) = RemoveLongOption(args, oi, true); args = rest; object value = typeParsers[optionNode.Type].DynamicInvoke(arg); optionNode.SetValue(verbObj, value); } } }
internal void AddChild(CategoryTree node) => Children.Add(node);