@@ -17,6 +17,7 @@ public ValueSubsystem(IAnnotationProvider? annotationProvider = null)
17
17
: base ( ValueAnnotations . Prefix , SubsystemKind . Version , annotationProvider )
18
18
{ }
19
19
20
+ //TODO: ExplicitDefault might have a valid null value, and thus try pattern. DefaultCalculation is only null when not present. Consider whether to use the same pattern (try on DefaultCalculation, even though it is not needed)
20
21
internal void SetExplicitDefault ( CliSymbol symbol , object ? defaultValue )
21
22
=> SetAnnotation ( symbol , ValueAnnotations . ExplicitDefault , defaultValue ) ;
22
23
internal object ? GetExplicitDefault ( CliSymbol symbol )
@@ -45,16 +46,19 @@ internal void SetDefaultCalculation(CliSymbol symbol, Func<object?> factory)
45
46
public AnnotationAccessor < Func < object ? > ? > DefaultCalculation
46
47
=> new ( this , ValueAnnotations . DefaultCalculation ) ;
47
48
48
- private void SetValue ( CliSymbol symbol , object ? value )
49
+ protected internal override bool GetIsActivated ( ParseResult ? parseResult )
50
+ => true ;
51
+
52
+ protected internal override CliExit Execute ( PipelineContext pipelineContext )
53
+ {
54
+ this . pipelineContext = pipelineContext ;
55
+ return CliExit . NotRun ( pipelineContext . ParseResult ) ;
56
+ }
57
+
58
+ // TODO: Consider using a simple dictionary instead of the annotation (@mhutch) because with is not useful here
59
+ private void SetValue < T > ( CliSymbol symbol , object ? value )
49
60
=> SetAnnotation ( symbol , ValueAnnotations . Value , value ) ;
50
- // TODO: Consider putting the logic in the generic version here
51
- // TODO: Consider using a simple dictionary instead of the annotation (@mhutch)
52
- // TODO: GetValue should call TryGetValue, not another call to TryGetAnnotation.
53
- // TODO: Should we provide an untyped value?
54
- private object ? GetValue ( CliSymbol symbol )
55
- => TryGetAnnotation < object ? > ( symbol , ValueAnnotations . Value , out var value )
56
- ? value
57
- : null ;
61
+ // TODO: Consider a way to disallow CliCommand here, as it creates a pit of failure.
58
62
private bool TryGetValue < T > ( CliSymbol symbol , out T ? value )
59
63
{
60
64
if ( TryGetAnnotation ( symbol , ValueAnnotations . Value , out var objectValue ) )
@@ -69,17 +73,13 @@ private bool TryGetValue<T>(CliSymbol symbol, out T? value)
69
73
//public AnnotationAccessor<object?> Value
70
74
// => new(this, ValueAnnotations.Value);
71
75
72
- protected internal override bool GetIsActivated ( ParseResult ? parseResult )
73
- => true ;
76
+ public T ? GetValue < T > ( CliOption option )
77
+ => GetValueInternal < T > ( option ) ;
78
+ public T ? GetValue < T > ( CliArgument argument )
79
+ => GetValueInternal < T > ( argument ) ;
74
80
75
- protected internal override CliExit Execute ( PipelineContext pipelineContext )
76
- {
77
- this . pipelineContext = pipelineContext ;
78
- return CliExit . NotRun ( pipelineContext . ParseResult ) ;
79
- }
80
-
81
- // @mhutch: I find this more readable than the if conditional version below. There will be at least two more blocks. Look good?
82
- public T ? GetValue < T > ( CliSymbol symbol )
81
+ // TODO: @mhutch: I find this more readable than the if conditional version below. There will be at least two more blocks. Look good?
82
+ private T ? GetValueInternal < T > ( CliSymbol symbol )
83
83
=> symbol switch
84
84
{
85
85
{ } when TryGetValue < T > ( symbol , out var value )
@@ -89,46 +89,47 @@ protected internal override CliExit Execute(PipelineContext pipelineContext)
89
89
// Value was not supplied during parsing, determine default now
90
90
{ } when GetDefaultCalculation ( symbol ) is { } defaultValueCalculation
91
91
=> UseValue ( symbol , CalculatedDefault < T > ( symbol , defaultValueCalculation ) ) ,
92
- { } when TryGetExplicitDefault < T > ( symbol , out var explicitValue ) => UseValue ( symbol , explicitValue ) ,
92
+ { } when TryGetExplicitDefault < T > ( symbol , out var explicitValue )
93
+ => UseValue ( symbol , explicitValue ) ,
93
94
null => throw new ArgumentNullException ( nameof ( symbol ) ) ,
94
95
_ => UseValue ( symbol , default ( T ) )
95
96
} ;
96
97
97
- public T ? GetValue2 < T > ( CliSymbol symbol )
98
- {
99
- if ( TryGetValue < T > ( symbol , out var value ) )
100
- {
101
- // It has already been retrieved at least once
102
- return value ;
103
- }
104
- if ( pipelineContext ? . ParseResult ? . GetValueResult ( symbol ) is ValueResult valueResult )
105
- {
106
- // Value was supplied during parsing
107
- return UseValue ( symbol , valueResult . GetValue < T > ( ) ) ;
108
- }
109
- // Value was not supplied during parsing, determine default now
110
- if ( GetDefaultCalculation ( symbol ) is { } defaultValueCalculation )
111
- {
112
- return UseValue ( symbol , CalculatedDefault ( symbol , defaultValueCalculation ) ) ;
113
- }
114
- if ( TryGetExplicitDefault < T > ( symbol , out var explicitValue ) )
115
- {
116
- return UseValue ( symbol , value ) ;
117
- }
118
- value = default ;
119
- SetValue ( symbol , value ) ;
120
- return value ;
121
-
122
- static T ? CalculatedDefault ( CliSymbol symbol , Func < object ? > defaultValueCalculation )
123
- {
124
- var objectValue = defaultValueCalculation ( ) ;
125
- var value = objectValue is null
126
- ? default
127
- : ( T ) objectValue ;
128
- return value ;
129
- }
130
- }
131
-
98
+ //// The following is temporarily included for showing why the above weird code is cleaner
99
+ //public T? GetValue2<T>(CliSymbol symbol)
100
+ //{
101
+ // if (TryGetValue<T>(symbol, out var value))
102
+ // {
103
+ // // It has already been retrieved at least once
104
+ // return value;
105
+ // }
106
+ // if (pipelineContext?.ParseResult?.GetValueResult(symbol) is ValueResult valueResult)
107
+ // {
108
+ // // Value was supplied during parsing
109
+ // return UseValue(symbol, valueResult.GetValue<T>());
110
+ // }
111
+ // // Value was not supplied during parsing, determine default now
112
+ // if (GetDefaultCalculation(symbol) is { } defaultValueCalculation)
113
+ // {
114
+ // return UseValue(symbol, CalculatedDefault(symbol, defaultValueCalculation));
115
+ // }
116
+ // if (TryGetExplicitDefault<T>(symbol, out var explicitValue))
117
+ // {
118
+ // return UseValue(symbol, value);
119
+ // }
120
+ // value = default ;
121
+ // SetValue<T>(symbol, value) ;
122
+ // return value;
123
+
124
+ // static T? CalculatedDefault(CliSymbol symbol, Func<object?> defaultValueCalculation)
125
+ // {
126
+ // var objectValue = defaultValueCalculation();
127
+ // var value = objectValue is null
128
+ // ? default
129
+ // : (T)objectValue ;
130
+ // return value;
131
+ // }
132
+ //}
132
133
133
134
private static T ? CalculatedDefault < T > ( CliSymbol symbol , Func < object ? > defaultValueCalculation )
134
135
{
@@ -141,9 +142,7 @@ protected internal override CliExit Execute(PipelineContext pipelineContext)
141
142
142
143
private T ? UseValue < T > ( CliSymbol symbol , T ? value )
143
144
{
144
- SetValue ( symbol , value ) ;
145
+ SetValue < T > ( symbol , value ) ;
145
146
return value ;
146
147
}
147
-
148
-
149
148
}
0 commit comments