44
55namespace System . CommandLine ;
66
7+ /// <summary>
8+ /// Contains the extension methods that are used to create value conditions
9+ /// </summary>
710public static class ValueConditionAnnotationExtensions
811{
12+ /// <summary>
13+ /// Set the upper and/or lower bound values of the range.
14+ /// </summary>
15+ /// <typeparam name="T">The type of the bounds.</typeparam>
16+ /// <param name="symbol">The option or argument the range applies to.</param>
17+ /// <param name="lowerBound">The lower bound of the range.</param>
18+ /// <param name="upperBound">The upper bound of the range.</param>
19+ // TODO: Add RangeBounds
20+ // TODO: You should not have to set both...why not nullable?
921 public static void SetRange < T > ( this CliValueSymbol symbol , T lowerBound , T upperBound )
1022 where T : IComparable < T >
1123 {
@@ -14,33 +26,35 @@ public static void SetRange<T>(this CliValueSymbol symbol, T lowerBound, T upper
1426 symbol . SetValueCondition ( range ) ;
1527 }
1628
17- public static void SetRange < T > ( this CliValueSymbol symbol , ValueSource < T > lowerBound , T upperBound )
18- where T : IComparable < T >
19- {
20- var range = new Range < T > ( lowerBound , upperBound ) ;
21-
22- symbol . SetValueCondition ( range ) ;
23- }
24-
25- public static void SetRange < T > ( this CliValueSymbol symbol , T lowerBound , ValueSource < T > upperBound )
26- where T : IComparable < T >
27- {
28- var range = new Range < T > ( lowerBound , upperBound ) ;
29-
30- symbol . SetValueCondition ( range ) ;
31- }
32-
29+ /// <summary>
30+ /// Set the upper and/or lower bound via ValueSource. Implicit conversions means this
31+ /// generally just works with any <see cref="ValueSource">.
32+ /// </summary>
33+ /// <typeparam name="T">The type of the bounds.</typeparam>
34+ /// <param name="symbol">The option or argument the range applies to.</param>
35+ /// <param name="lowerBound">The <see cref="ValueSource"> that is the lower bound of the range.</param>
36+ /// <param name="upperBound">The <see cref="ValueSource"> that is the upper bound of the range.</param>
37+ // TODO: Add RangeBounds
38+ // TODO: You should not have to set both...why not nullable?
3339 public static void SetRange < T > ( this CliValueSymbol symbol , ValueSource < T > lowerBound , ValueSource < T > upperBound )
34- where T : IComparable < T >
40+ where T : IComparable < T >
41+ // TODO: You should not have to set both...why not nullable?
3542 {
3643 var range = new Range < T > ( lowerBound , upperBound ) ;
3744
3845 symbol . SetValueCondition ( range ) ;
3946 }
4047
41- public static void SetInclusiveGroup ( this CliCommand symbol , IEnumerable < CliValueSymbol > group )
42- => symbol . SetValueCondition ( new InclusiveGroup ( group ) ) ;
48+ /// <summary>
49+ /// Indicates that there is an inclusive group of options and arguments for the command. All
50+ /// members of an inclusive must be present, or none can be present.
51+ /// </summary>
52+ /// <param name="command">The command the inclusive group applies to.</param>
53+ /// <param name="group">The group of options and arguments that must all be present, or none can be present.</param>
54+ public static void SetInclusiveGroup ( this CliCommand command , IEnumerable < CliValueSymbol > group )
55+ => command . SetValueCondition ( new InclusiveGroup ( group ) ) ;
4356
57+ // TODO: This should not be public if ValueConditions are not public
4458 public static void SetValueCondition < TValueSymbol , TValueCondition > ( this TValueSymbol symbol , TValueCondition valueCondition )
4559 where TValueSymbol : CliValueSymbol
4660 where TValueCondition : ValueCondition
@@ -53,33 +67,63 @@ public static void SetValueCondition<TValueSymbol, TValueCondition>(this TValueS
5367 valueConditions . Add ( valueCondition ) ;
5468 }
5569
56- public static void SetValueCondition < TValueCondition > ( this CliCommand symbol , TValueCondition valueCondition )
57- where TValueCondition : CommandCondition
70+ // TODO: This should not be public if ValueConditions are not public
71+ public static void SetValueCondition < TCommandCondition > ( this CliCommand symbol , TCommandCondition commandCondition )
72+ where TCommandCondition : CommandCondition
5873 {
5974 if ( ! symbol . TryGetAnnotation < List < CommandCondition > > ( ValueConditionAnnotations . ValueConditions , out var valueConditions ) )
6075 {
6176 valueConditions = [ ] ;
6277 symbol . SetAnnotation ( ValueConditionAnnotations . ValueConditions , valueConditions ) ;
6378 }
64- valueConditions . Add ( valueCondition ) ;
79+ valueConditions . Add ( commandCondition ) ;
6580 }
6681
82+ /// <summary>
83+ /// Gets a list of conditions on an option or argument.
84+ /// </summary>
85+ /// <param name="command">The option or argument to get the conditions for.</param>
86+ /// <returns>The conditions that have been applied to the option or argument.</returns>
87+ ///
88+ // TODO: This is public because it will be used by other subsystems we might not own. It could be an extension method the subsystem namespace
6789 public static List < ValueCondition > ? GetValueConditions ( this CliValueSymbol symbol )
6890 => symbol . TryGetAnnotation < List < ValueCondition > > ( ValueConditionAnnotations . ValueConditions , out var valueConditions )
6991 ? valueConditions
7092 : null ;
7193
72- public static List < CommandCondition > ? GetCommandConditions ( this CliCommand symbol )
73- => symbol . TryGetAnnotation < List < CommandCondition > > ( ValueConditionAnnotations . ValueConditions , out var valueConditions )
94+ /// <summary>
95+ /// Gets a list of conditions on a command.
96+ /// </summary>
97+ /// <param name="command">The command to get the conditions for.</param>
98+ /// <returns>The conditions that have been applied to the command.</returns>
99+ ///
100+ // TODO: This is public because it will be used by other subsystems we might not own. It could be an extension method the subsystem namespace
101+ public static List < CommandCondition > ? GetCommandConditions ( this CliCommand command )
102+ => command . TryGetAnnotation < List < CommandCondition > > ( ValueConditionAnnotations . ValueConditions , out var valueConditions )
74103 ? valueConditions
75104 : null ;
76105
106+ /// <summary>
107+ /// Gets the condition that matches the type, if it exists on this option or argument.
108+ /// </summary>
109+ /// <typeparam name="TCondition">The type of condition to return.</typeparam>
110+ /// <param name="symbol">The option or argument that may contain the condition.</param>
111+ /// <returns>The condition if it exists on the option or argument, otherwise null.</returns>
112+ // This method feels useful because it clarifies that last should win and returns one, when only one should be applied
113+ // TODO: Consider removing user facing naming, other than the base type, that is Value or CommandCondition and just use Condition
77114 public static TCondition ? GetValueCondition < TCondition > ( this CliValueSymbol symbol )
78115 where TCondition : ValueCondition
79116 => ! symbol . TryGetAnnotation ( ValueConditionAnnotations . ValueConditions , out List < ValueCondition > ? valueConditions )
80117 ? null
81118 : valueConditions . OfType < TCondition > ( ) . LastOrDefault ( ) ;
82119
120+ /// <summary>
121+ /// Gets the condition that matches the type, if it exists on this command.
122+ /// </summary>
123+ /// <typeparam name="TCondition">The type of condition to return.</typeparam>
124+ /// <param name="symbol">The command that may contain the condition.</param>
125+ /// <returns>The condition if it exists on the command, otherwise null.</returns>
126+ // This method feels useful because it clarifies that last should win and returns one, when only one should be applied
83127 public static TCondition ? GetCommandCondition < TCondition > ( this CliCommand symbol )
84128 where TCondition : CommandCondition
85129 => ! symbol . TryGetAnnotation ( ValueConditionAnnotations . ValueConditions , out List < CommandCondition > ? valueConditions )
0 commit comments