Macro daml_macro::daml_path
source · [−]macro_rules! daml_path {
( @priv $record:ident / $path:ident $( { => $variant:ident } )? [ $index:expr ] ? $( :: $type:ident )? ) => { ... };
( @priv $record:ident / $path:ident $( { => $variant:ident } )? [ $index:expr ] $( :: $type:ident )? ) => { ... };
( @priv $record:ident / $path:ident $( { => $variant:ident } )? $( :: $type:ident )? ) => { ... };
( @priv $record:ident / $path:ident $( { => $variant:ident } )? ? $( :: $type:ident )? ) => { ... };
( @priv $record:ident / $path:ident $( { => $variant:ident } )? [ $index:expr ] ? $($rest:tt)* ) => { ... };
( @priv $record:ident / $path:ident $( { => $variant:ident } )? [ $index:expr ] $($rest:tt)* ) => { ... };
( @priv $record:ident / $path:ident $( { => $variant:ident } )? ? $($rest:tt)* ) => { ... };
( @priv $record:ident / $path:ident { => $variant:ident } $($rest0:tt)* ) => { ... };
( @priv $record:ident / $path:ident $( { => $variant:ident } )? $($rest1:tt)* ) => { ... };
( @priv $value:ident ) => { ... };
( @priv c $value:ident ) => { ... };
( @priv u $value:ident ) => { ... };
( @priv p $value:ident ) => { ... };
( @priv i $value:ident ) => { ... };
( @priv f $value:ident ) => { ... };
( @priv t $value:ident ) => { ... };
( @priv b $value:ident ) => { ... };
( @priv s $value:ident ) => { ... };
( @priv d $value:ident ) => { ... };
( @priv r $value:ident ) => { ... };
( @priv l $value:ident ) => { ... };
( @priv v $value:ident ) => { ... };
( @get_record_field $record:ident, $path:ident ) => { ... };
( @get_list_item $value:ident, $index:expr ) => { ... };
( @get_variant_value $value:ident , $variant:ident ) => { ... };
( @get_variant_value $value:ident , ) => { ... };
( $($rest:tt)* ) => { ... };
}Expand description
Construct a Daml data extractor function from a path expression.
This macro provides a concise DSL for constructing a Daml data extractor closure as required by
DamlRecord::extract and DamlValue::extract. The closure produced will have the following signature:
Fn(&DamlRecord) -> DamlResult<R>
The type of R depends on the path expression provided and may either be a reference to a DamlValue or a
reference to another type such as &str.
Syntax
Path expressions take the following form (pseudo-regex syntax):
field ( '{' '=>' variant '}' )? ( '[' index ']' )? ( '?' )? ( '/' ... )* ( '::' type )?
----- ------------------------- ------------------ -------- - --- --- -- --------------
(1) (2) (3) (4) | (5) (6) | (7)Each field corresponds to a labelled DamlRecordField within the DamlRecord on which the data extractor
is to be executed.
Syntax Items:
- the
fieldof the currentDamlValue::Recordto traverse - extract the
DamlValueiffieldis aDamlValue::Variantandvariantmatches the constructor. - extract the
DamlValuefrom list atindex(expression) iffieldis aDamlValue::List - extract the
DamlValueiffieldis aDamlValue::Optional - a separator between
fieldentries - a repeat of items
(1),(2),(3)&(4). Items(5)&(6)are repeated zero or many times. - an optional type specifier
Note that any or all of (2), (3) & (4) can be applied for a single field and will run consecutively. i.e.
in the single path field people{=>Persons}[0]? will interpret people as a DamlValue::Variant with a
constructor of Persons which is a DamlValue::List which has an element at index 0 which contain an
DamlValue::Optional that is a DamlValue::Int64.
Note that the path expression is not whitespace sensitive.
Fields which are nested DamlRecord can be traversed by chaining together multiple field elements delimited
with a / character. Nesting can be of arbitrary depth (up to the default recursive macro limit). Attempting
to access a non-existent field will return in an UnknownField error being returned.
List elements of fields which are of type DamlValue::List can be accessed by specifying a list index
expression inside [] braces. A ListIndexOutOfRange error will be returned if an attempt is made to access
lists elements outside the available bounds.
Optional fields of type DamlValue::Optional can be accessed by appending a ? character to the record
field name or list element. If the optional is Some then the embedded DamlValue is extracted and
processing of the path expression continues. If the optional is None then a MissingRequiredField error
will be returned.
The final field may optionally have a type specifier by appending a :: token followed by one
of several supported type specifier codes. If no type specifier code is provided then the expression will
return a DamlValue otherwise a type appropriate to the specifier will be returned.
If the constructor of a DamlValue::Variant does not match then UnexpectedVariant error is returned. The
special variant value of __ can be used to indicate that any variant is acceptable. Attempting to access the
nested DamlValue within a variant will produce an error if the type of the item does not match the actual
variant type.
The supported type specifiers are:
| code | name | Rust type | value variant |
|---|---|---|---|
c | contract id | &str | DamlValue::ContractId |
u | unit | &() | DamlValue::Unit |
p | party | &str | DamlValue::Party |
i | int64 | &i64 | DamlValue::Int64 |
f | numeric | &BigInteger | DamlValue::Numeric |
t | text | &str | DamlValue::Text |
s | timestamp | &DateTime<Utc> | DamlValue::Timestamp |
b | boolean | &bool | DamlValue::Bool |
d | date | &Date<Utc> | DamlValue::Date |
r | record | &DamlRecord | DamlValue::Record |
l | list | &Vec<DamlValue> | DamlValue::List |
v | variant | &DamlVariant | DamlValue::Variant |
Limitations
Path expressions only support labelled DamlRecordField fields. Accessing unlabelled fields will result in
an UnknownField error being returned.
Accessing values from a list-of-list is not supported and therefore path expression syntax my_list[0][1] is not
valid. To access the sublist first extract the parent list with the path expression my_list[0] and then apply a
second path expression to the resulting DamlValue. Note that a list containing DamlRecord which in turn
contains nested lists is supported.
All type specifiers return references, even for simple copy types, and so must be dereferenced as needed.
There is currently no support for DamlValue::Map, DamlValue::GenMap or DamlValue::Enum.
Examples
let value = daml_value![{
party: "Alice"::p,
trade: {
trade_id: 123,
counterparty: "Bob"::p,
trade_details: {
ticker: "GOOG",
prices: [1231.54, 1234.85, 1237.92]
},
order_type: {?= "MarketOrder"}
}
}];
assert_eq!("Alice", value.extract(daml_path![party::p])?);
assert_eq!(123, *value.extract(daml_path![trade/trade_id::i])?);
assert_eq!("Bob", value.extract(daml_path![trade/counterparty::p])?);
assert_eq!("GOOG", value.extract(daml_path![trade/trade_details/ticker::t])?);
assert_eq!(&BigDecimal::try_from(1234.85).unwrap(),
value.extract(daml_path![trade/trade_details/prices[1]::f])?);
assert_eq!("MarketOrder", value.extract(daml_path![trade/order_type?::t])?);