@@ -56,6 +56,220 @@ def __call__(self, ctx, value):
5656 return value
5757
5858
59+ class AAZDurationFormat (AAZBaseArgFormat ):
60+
61+ def __call__ (self , ctx , value ):
62+ assert isinstance (value , AAZSimpleValue )
63+ data = value ._data
64+ if data == AAZUndefined or data is None or value ._is_patch :
65+ return value
66+
67+ assert isinstance (data , str )
68+ from msrest .serialization import Serializer
69+ from isodate .isoerror import ISO8601Error
70+
71+ try :
72+ data = Serializer .serialize_duration (data .upper ())
73+ except ISO8601Error :
74+ try :
75+ # parse '##DT##H##M##S
76+ data = Serializer .serialize_duration (f'P0M{ data .upper ()} ' )
77+ except ISO8601Error :
78+ try :
79+ # parse '##H##M##S'
80+ data = Serializer .serialize_duration (f'PT{ data .upper ()} ' )
81+ except ISO8601Error :
82+ raise AAZInvalidArgValueError (
83+ f"Invalid format: '{ data } ' should be of the form "
84+ f"'##dT##h##m##s', '##h##m##s' or ISO8601 duration"
85+ )
86+ value ._data = data
87+ return value
88+
89+
90+ class AAZDateFormat (AAZBaseArgFormat ):
91+
92+ def __init__ (self ):
93+ self .help_string = 'Format: date (yyyy-mm-dd)'
94+
95+ def __call__ (self , ctx , value ):
96+ assert isinstance (value , AAZSimpleValue )
97+ data = value ._data
98+ if data == AAZUndefined or data is None or value ._is_patch :
99+ return value
100+
101+ assert isinstance (data , str )
102+ import dateutil .parser
103+ import dateutil .tz
104+
105+ dt_val = None
106+ try :
107+ dt_val = dateutil .parser .parse (data )
108+ except ValueError :
109+ pass
110+
111+ if not dt_val :
112+ raise AAZInvalidArgValueError (
113+ f"Unable to parse: '{ data } '. Expected format: { self .help_string } "
114+ )
115+
116+ if any ([dt_val .hour , dt_val .minute , dt_val .second , dt_val .microsecond ]):
117+ logger .warning ('Time info will be ignored in %s.' , data )
118+
119+ if dt_val .tzinfo :
120+ logger .warning ('Timezone info will be ignored in %s.' , data )
121+
122+ data = "{:04}-{:02}-{:02}" .format (dt_val .year , dt_val .month , dt_val .day )
123+ value ._data = data
124+ return value
125+
126+
127+ class AAZTimeFormat (AAZBaseArgFormat ):
128+
129+ def __init__ (self ):
130+ self .help_string = 'Format: time (hh:mm:ss.xxxxxx)'
131+
132+ def __call__ (self , ctx , value ):
133+ assert isinstance (value , AAZSimpleValue )
134+ data = value ._data
135+ if data == AAZUndefined or data is None or value ._is_patch :
136+ return value
137+
138+ assert isinstance (data , str )
139+ import dateutil .parser
140+ import dateutil .tz
141+
142+ dt_val = None
143+ try :
144+ dt_val = dateutil .parser .parse (data )
145+ except ValueError :
146+ pass
147+
148+ if not dt_val :
149+ raise AAZInvalidArgValueError (
150+ f"Unable to parse: '{ data } '. Expected format: { self .help_string } "
151+ )
152+
153+ if any ([dt_val .day , dt_val .month , dt_val .year ]):
154+ logger .warning ('Date info will be ignored in %s.' , data )
155+
156+ if dt_val .tzinfo :
157+ logger .warning ('Timezone info will be ignored in %s.' , data )
158+
159+ data = "{:02}:{:02}:{:02}" .format (dt_val .hour , dt_val .minute , dt_val .second )
160+ if dt_val .microsecond :
161+ microseconds = str (dt_val .microsecond ).rjust (6 , '0' ).rstrip ('0' ).ljust (3 , '0' )
162+ data += '.' + microseconds
163+
164+ value ._data = data
165+ return value
166+
167+
168+ class AAZDateTimeFormat (AAZBaseArgFormat ):
169+
170+ def __init__ (self , protocol = "iso" ):
171+ self .protocol = protocol
172+ self .help_string = 'Format: date (yyyy-mm-dd) time (hh:mm:ss.xxxxxx) timezone (+/-hh:mm)'
173+
174+ def __call__ (self , ctx , value ):
175+ assert isinstance (value , AAZSimpleValue )
176+ data = value ._data
177+ if data == AAZUndefined or data is None or value ._is_patch :
178+ return value
179+
180+ assert isinstance (data , str )
181+ import dateutil .parser
182+ import dateutil .tz
183+ from msrest .serialization import Serializer
184+
185+ dt_val = None
186+ try :
187+ dt_val = dateutil .parser .parse (data )
188+ except ValueError :
189+ pass
190+
191+ if not dt_val :
192+ raise AAZInvalidArgValueError (
193+ f"Unable to parse: '{ data } '. Expected format: { self .help_string } "
194+ )
195+
196+ if not dt_val .tzinfo :
197+ dt_val = dt_val .replace (tzinfo = dateutil .tz .tzlocal ())
198+
199+ if self .protocol == "iso" :
200+ data = Serializer .serialize_iso (dt_val )
201+ elif self .protocol == "rfc" :
202+ data = Serializer .serialize_rfc (dt_val )
203+ else :
204+ raise NotImplementedError ()
205+
206+ value ._data = data
207+ return value
208+
209+
210+ class AAZUuidFormat (AAZBaseArgFormat ):
211+
212+ _uuid_pattern = re .compile (r'^[{(]?[0-9a-fA-F]{8}([-]?[0-9a-fA-F]{4}){3}[-]?[0-9a-fA-F]{12}[)}]?$' )
213+
214+ def __init__ (self , case = None , braces_removed = True , hyphens_filled = True ):
215+ """
216+ :param case: 'upper' to format data into upper case, 'lower' to format data into lower case
217+ """
218+ self .case = case
219+ self .braces_removed = braces_removed
220+ self .hyphens_filled = hyphens_filled
221+
222+ def __call__ (self , ctx , value ):
223+ assert isinstance (value , AAZSimpleValue )
224+ data = value ._data
225+ if data == AAZUndefined or data is None or value ._is_patch :
226+ return value
227+
228+ assert isinstance (data , str )
229+ if not self ._uuid_pattern .fullmatch (data ):
230+ raise AAZInvalidArgValueError (
231+ f"Invalid format: '{ data } ' is not a valid GUID or UUID"
232+ )
233+
234+ if '-' in data and data .count ('-' ) != 4 :
235+ raise AAZInvalidArgValueError (
236+ f"Invalid format: '{ data } ' is not a valid GUID or UUID"
237+ )
238+
239+ if data .startswith ('{' ) or data .endswith ('}' ):
240+ # remove braces
241+ if not (data .startswith ('{' ) and data .endswith ('}' )):
242+ raise AAZInvalidArgValueError (
243+ f"Invalid format: '{ data } ' is not a valid GUID or UUID"
244+ )
245+ if self .braces_removed :
246+ data = data [1 :- 1 ]
247+
248+ elif data .startswith ('(' ) or data .endswith (')' ):
249+ # remove parentheses
250+ if not (data .startswith ('(' ) and data .endswith (')' )):
251+ raise AAZInvalidArgValueError (
252+ f"Invalid format: '{ data } ' is not a valid GUID or UUID"
253+ )
254+ if self .braces_removed :
255+ data = data [1 :- 1 ]
256+
257+ if '-' not in data and self .hyphens_filled :
258+ # add '-' in data
259+ if data [0 ] in ('{' , '(' ):
260+ data = f'{ data [:9 ]} -{ data [9 :13 ]} -{ data [13 :17 ]} -{ data [17 :21 ]} -{ data [21 :]} '
261+ else :
262+ data = f'{ data [:8 ]} -{ data [8 :12 ]} -{ data [12 :16 ]} -{ data [16 :20 ]} -{ data [20 :]} '
263+
264+ if self .case == 'upper' :
265+ data = data .upper ()
266+ elif self .case == 'lower' :
267+ data = data .lower ()
268+
269+ value ._data = data
270+ return value
271+
272+
59273class AAZIntArgFormat (AAZBaseArgFormat ):
60274
61275 def __init__ (self , multiple_of = None , maximum = None , minimum = None ):
0 commit comments