@@ -1360,6 +1360,165 @@ pub fn compile_code_with_state(
13601360 Err ( anyhow ! ( "Could not parse ratslang code." ) )
13611361}
13621362
1363+ // -- Macros --
1364+
1365+ /// Gets a length range.
1366+ /// It handles `..` and `100mm..2000mm` syntax, converting all values to meters (f32).
1367+ #[ macro_export]
1368+ macro_rules! resolve_length_range_meters_float {
1369+ ( $ns: expr, $field: expr, $default_from: expr, $default_to: expr) => { {
1370+ let convert_mm_to_meters = |val: & Val | -> anyhow:: Result <f32 > {
1371+ match val {
1372+ Val :: UnitedVal ( uv) if uv. unit == Unit :: WayMillimeter => {
1373+ Ok ( Length :: new:: <millimeter>( uv. val as f32 ) . get:: <meter>( ) )
1374+ } ,
1375+ _ => Err ( anyhow!( "Expected a united value with 'mm' unit for length range '{}'" , $field) )
1376+ }
1377+ } ;
1378+
1379+ let rhs_val = resolve_var!( $ns, $field, as & Rhs , r => { r} ) ?;
1380+ match rhs_val {
1381+ Rhs :: EmptyRange => Ok ( ( $default_from, $default_to) ) ,
1382+ Rhs :: Range { from, to } => {
1383+ let from_val = from. as_ref( ) . map_or( Ok ( $default_from) , |v| convert_mm_to_meters( v) ) ?;
1384+ let to_val = to. as_ref( ) . map_or( Ok ( $default_to) , |v| convert_mm_to_meters( v) ) ?;
1385+ Ok ( ( from_val, to_val) )
1386+ }
1387+ _ => Err ( anyhow!( "Expected a range expression for field '{}'" , $field) )
1388+ }
1389+ } } ;
1390+ }
1391+
1392+ #[ macro_export]
1393+ macro_rules! resolve_var {
1394+ // Arm for variable names passed as identifiers
1395+ ( $asts: expr, $var_name_ident: ident, as $target_type: ty, $( $pattern: pat_param) |+ => $extraction_block: block) => { {
1396+ let __var_name_str = stringify!( $var_name_ident) ;
1397+ let __resolved_opt = match $asts. user. resolve( __var_name_str) ? {
1398+ Some ( val) => Some ( val) ,
1399+ None => $asts. defaults. resolve( __var_name_str) ?,
1400+ } ;
1401+
1402+ match __resolved_opt {
1403+ Some ( __resolved_val) => match __resolved_val {
1404+ $( $pattern) |+ => {
1405+ let __extracted_val = $extraction_block;
1406+ Ok ( __extracted_val)
1407+ }
1408+ _ => Err ( anyhow!( format!(
1409+ "Pattern mismatch for '{}'. Expected pattern for type `{}`." ,
1410+ __var_name_str,
1411+ stringify!( $target_type)
1412+ ) ) ) ,
1413+ } ?
1414+ . try_into( )
1415+ . map_err( |e| {
1416+ anyhow!(
1417+ "Failed to convert '{}' to type `{}`: {:?}" ,
1418+ __var_name_str,
1419+ stringify!( $target_type) ,
1420+ e
1421+ )
1422+ } ) ,
1423+ None => Err ( anyhow!( concat!(
1424+ "Required variable '" ,
1425+ stringify!( $var_name_ident) ,
1426+ "' not found in any configuration."
1427+ ) ) ) ,
1428+ }
1429+ } } ;
1430+
1431+ // Arm for variable names passed as string expressions
1432+ ( $asts: expr, $var_name_expr: expr, as $target_type: ty, $( $pattern: pat_param) |+ => $extraction_block: block) => { {
1433+ let __var_name_str = $var_name_expr;
1434+ let __resolved_opt = match $asts. user. resolve( __var_name_str) ? {
1435+ Some ( val) => Some ( val) ,
1436+ None => $asts. defaults. resolve( __var_name_str) ?,
1437+ } ;
1438+
1439+ match __resolved_opt {
1440+ Some ( __resolved_val) => match __resolved_val {
1441+ $( $pattern) |+ => {
1442+ let __extracted_val = $extraction_block;
1443+ Ok ( __extracted_val)
1444+ }
1445+ _ => Err ( anyhow!( format!(
1446+ "Pattern mismatch for '{}'. Expected pattern for type `{}`." ,
1447+ __var_name_str,
1448+ stringify!( $target_type)
1449+ ) ) ) ,
1450+ } ?
1451+ . try_into( )
1452+ . map_err( |e| {
1453+ anyhow!(
1454+ "Failed to convert '{}' to type `{}`: {:?}" ,
1455+ __var_name_str,
1456+ stringify!( $target_type) ,
1457+ e
1458+ )
1459+ } ) ,
1460+ None => Err ( anyhow!( format!(
1461+ "Required variable '{}' not found in any configuration." ,
1462+ __var_name_str
1463+ ) ) ) ,
1464+ }
1465+ } } ;
1466+ }
1467+
1468+ /// Gets a range from floating numbers while also accepting integers by converting them to floats.
1469+ #[ macro_export]
1470+ macro_rules! resolve_float_force_range {
1471+ ( $ns: expr, $field: expr, $default_from: expr, $default_to: expr) => { {
1472+ let rhs_val = resolve_var!( $ns, $field, as & Rhs , r => { r} ) ?;
1473+ match rhs_val {
1474+ Rhs :: EmptyRange => Ok ( ( $default_from, $default_to) ) ,
1475+ Rhs :: Range { from, to } => {
1476+ let from_val = match from {
1477+ Some ( Val :: NumVal ( NumVal :: Floating ( f) ) ) => f as f32 ,
1478+ Some ( Val :: NumVal ( NumVal :: Integer ( i) ) ) => i as f32 ,
1479+ None => $default_from,
1480+ _ => return Err ( anyhow!( format!( "Expected numeric value for 'from' in float range '{}'" , $field) ) ) ,
1481+ } ;
1482+ let to_val = match to {
1483+ Some ( Val :: NumVal ( NumVal :: Floating ( f) ) ) => f as f32 ,
1484+ Some ( Val :: NumVal ( NumVal :: Integer ( i) ) ) => i as f32 ,
1485+ None => $default_to,
1486+ _ => return Err ( anyhow!( format!( "Expected numeric value for 'to' in float range '{}'" , $field) ) ) ,
1487+ } ;
1488+ Ok ( ( from_val, to_val) )
1489+ } ,
1490+ _ => Err ( anyhow!( format!( "Expected a range expression for field '{}'" , $field) ) )
1491+ }
1492+ } } ;
1493+ }
1494+
1495+ /// Gets a range from floating numbers without implicit conversions.
1496+ #[ macro_export]
1497+ macro_rules! resolve_float_range {
1498+ ( $ns: expr, $field: expr, $default_from: expr, $default_to: expr) => { {
1499+ let rhs_val = resolve_var!( $ns, $field, as & Rhs , r => { r} ) ?;
1500+ match rhs_val {
1501+ Rhs :: EmptyRange => Ok ( ( $default_from, $default_to) ) ,
1502+ Rhs :: Range { from, to } => {
1503+ let from_val = match from {
1504+ Some ( Val :: NumVal ( NumVal :: Floating ( f) ) ) => f as f32 ,
1505+ Some ( Val :: NumVal ( NumVal :: Integer ( _) ) ) => return Err ( anyhow!( format!( "Expected floating value for 'from' in float range '{}'" , $field) ) ) ,
1506+ None => $default_from,
1507+ _ => return Err ( anyhow!( format!( "Expected numeric value for 'from' in float range '{}'" , $field) ) ) ,
1508+ } ;
1509+ let to_val = match to {
1510+ Some ( Val :: NumVal ( NumVal :: Floating ( f) ) ) => f as f32 ,
1511+ Some ( Val :: NumVal ( NumVal :: Integer ( _) ) ) => return Err ( anyhow!( format!( "Expected floating value for 'from' in float range '{}'" , $field) ) ) ,
1512+ None => $default_to,
1513+ _ => return Err ( anyhow!( format!( "Expected numeric value for 'to' in float range '{}'" , $field) ) ) ,
1514+ } ;
1515+ Ok ( ( from_val, to_val) )
1516+ } ,
1517+ _ => Err ( anyhow!( format!( "Expected a range expression for field '{}'" , $field) ) )
1518+ }
1519+ } } ;
1520+ }
1521+
13631522#[ cfg( test) ]
13641523mod tests {
13651524 use super :: * ;
0 commit comments