@@ -219,6 +219,28 @@ pub enum PrmValueConstraint {
219219 Unconstrained ,
220220}
221221
222+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
223+ pub struct PrmValueConstraintError {
224+ value : i64 ,
225+ constraint : PrmValueConstraint ,
226+ }
227+
228+ impl std:: fmt:: Display for PrmValueConstraintError {
229+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
230+ match & self . constraint {
231+ PrmValueConstraint :: MinMax ( min, max) => {
232+ write ! ( f, "value {} not in range {min}..={max}" , self . value)
233+ }
234+ PrmValueConstraint :: Enum ( values) => {
235+ write ! ( f, "value {} not in set {values:?}" , self . value)
236+ }
237+ PrmValueConstraint :: Unconstrained => unreachable ! ( ) ,
238+ }
239+ }
240+ }
241+
242+ impl std:: error:: Error for PrmValueConstraintError { }
243+
222244impl PrmValueConstraint {
223245 pub fn is_valid ( & self , value : i64 ) -> bool {
224246 match self {
@@ -228,21 +250,29 @@ impl PrmValueConstraint {
228250 }
229251 }
230252
231- pub fn assert_valid ( & self , value : i64 ) {
253+ pub fn assert_valid ( & self , value : i64 ) -> Result < ( ) , PrmValueConstraintError > {
232254 match self {
233255 PrmValueConstraint :: MinMax ( min, max) => {
234- assert ! (
235- * min <= value && value <= * max,
236- "value {value} not in range {min}..={max}" ,
237- ) ;
256+ if * min > value || value > * max {
257+ Err ( PrmValueConstraintError {
258+ value,
259+ constraint : self . clone ( ) ,
260+ } )
261+ } else {
262+ Ok ( ( ) )
263+ }
238264 }
239265 PrmValueConstraint :: Enum ( values) => {
240- assert ! (
241- values. contains( & value) ,
242- "value {value} not in set {values:?}" ,
243- ) ;
266+ if !values. contains ( & value) {
267+ Err ( PrmValueConstraintError {
268+ value,
269+ constraint : self . clone ( ) ,
270+ } )
271+ } else {
272+ Ok ( ( ) )
273+ }
244274 }
245- PrmValueConstraint :: Unconstrained => ( ) ,
275+ PrmValueConstraint :: Unconstrained => Ok ( ( ) ) ,
246276 }
247277 }
248278}
@@ -370,6 +400,46 @@ pub struct GenericStationDescription {
370400 pub unit_diag : UnitDiag ,
371401}
372402
403+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
404+ pub enum SetPrmError {
405+ PrmNotFound ( String ) ,
406+ PrmWithoutTexts ( String ) ,
407+ PrmTextNotFound { prm : String , text : String } ,
408+ ValueConstraint ( PrmValueConstraintError ) ,
409+ ValueRange { value : i64 , ty : UserPrmDataType } ,
410+ }
411+
412+ impl From < PrmValueConstraintError > for SetPrmError {
413+ fn from ( value : PrmValueConstraintError ) -> Self {
414+ Self :: ValueConstraint ( value)
415+ }
416+ }
417+
418+ impl std:: fmt:: Display for SetPrmError {
419+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
420+ match self {
421+ SetPrmError :: PrmNotFound ( name) => {
422+ write ! ( f, "prm {name} was not found" )
423+ }
424+ SetPrmError :: ValueConstraint ( prm_value_constraint_error) => {
425+ prm_value_constraint_error. fmt ( f)
426+ }
427+ SetPrmError :: ValueRange { value, ty } => {
428+ write ! ( f, "value {value} is out of range for type {ty:?}" )
429+ }
430+ SetPrmError :: PrmWithoutTexts ( name) => {
431+ write ! ( f, "prm {name} does not have texts" )
432+ }
433+ SetPrmError :: PrmTextNotFound { prm, text } => {
434+ write ! ( f, "prm {prm} does not have text {text:?}" )
435+ }
436+ }
437+ }
438+ }
439+
440+ impl std:: error:: Error for SetPrmError { }
441+
442+ #[ derive( Debug , PartialEq , Eq ) ]
373443pub struct PrmBuilder < ' a > {
374444 desc : & ' a UserPrmData ,
375445 prm : Vec < u8 > ,
@@ -412,37 +482,49 @@ impl<'a> PrmBuilder<'a> {
412482 Ok ( ( ) )
413483 }
414484
415- pub fn set_prm ( & mut self , prm : & str , value : i64 ) -> Result < & mut Self , PrmValueRangeError > {
485+ pub fn set_prm ( & mut self , prm : & str , value : i64 ) -> Result < & mut Self , SetPrmError > {
416486 let ( offset, data_ref) = self
417487 . desc
418488 . data_ref
419489 . iter ( )
420490 . find ( |( _, r) | r. name == prm)
421- . expect ( "TODO" ) ;
422- data_ref. constraint . assert_valid ( value) ;
491+ . ok_or_else ( || SetPrmError :: PrmNotFound ( prm . to_string ( ) ) ) ? ;
492+ data_ref. constraint . assert_valid ( value) ? ;
423493 data_ref
424494 . data_type
425- . write_value_to_slice ( value, & mut self . prm [ ( * offset) ..] ) ?;
495+ . write_value_to_slice ( value, & mut self . prm [ ( * offset) ..] )
496+ . map_err ( |_e| SetPrmError :: ValueRange {
497+ value,
498+ ty : data_ref. data_type ,
499+ } ) ?;
426500 Ok ( self )
427501 }
428502
429- pub fn set_prm_from_text (
430- & mut self ,
431- prm : & str ,
432- value : & str ,
433- ) -> Result < & mut Self , PrmValueRangeError > {
503+ pub fn set_prm_from_text ( & mut self , prm : & str , value : & str ) -> Result < & mut Self , SetPrmError > {
434504 let ( offset, data_ref) = self
435505 . desc
436506 . data_ref
437507 . iter ( )
438508 . find ( |( _, r) | r. name == prm)
439- . expect ( "TODO" ) ;
440- let text_ref = data_ref. text_ref . as_ref ( ) . expect ( "TODO" ) ;
441- let value = * text_ref. get ( value) . expect ( "TODO" ) ;
442- data_ref. constraint . assert_valid ( value) ;
509+ . ok_or_else ( || SetPrmError :: PrmNotFound ( prm. to_string ( ) ) ) ?;
510+ let text_ref = data_ref
511+ . text_ref
512+ . as_ref ( )
513+ . ok_or_else ( || SetPrmError :: PrmWithoutTexts ( prm. to_string ( ) ) ) ?;
514+ let value = * text_ref
515+ . get ( value)
516+ . ok_or_else ( || SetPrmError :: PrmTextNotFound {
517+ prm : prm. to_string ( ) ,
518+ text : value. to_string ( ) ,
519+ } ) ?;
520+ data_ref. constraint . assert_valid ( value) ?;
443521 data_ref
444522 . data_type
445- . write_value_to_slice ( value, & mut self . prm [ ( * offset) ..] ) ?;
523+ . write_value_to_slice ( value, & mut self . prm [ ( * offset) ..] )
524+ . map_err ( |_e| SetPrmError :: ValueRange {
525+ value,
526+ ty : data_ref. data_type ,
527+ } ) ?;
446528 Ok ( self )
447529 }
448530
0 commit comments