macro_rules! daml_value {
() => { ... };
([ $( $value:tt $( :: $type:ident )? ),* ]) => { ... };
( { $( $label:ident : $value:tt $( :: $type:ident )? ),* } ) => { ... };
( { => $variant:ident $($value:tt)* } ) => { ... };
( { ?= $($value:tt)* } ) => { ... };
( { ?! } ) => { ... };
($prim:expr) => { ... };
($party:tt :: p) => { ... };
($contract:tt :: c) => { ... };
($timestamp:tt :: t) => { ... };
($date:tt :: d) => { ... };
(@priv p $party:expr) => { ... };
(@priv c $contract:expr) => { ... };
(@priv t $timestamp:expr) => { ... };
(@priv d $date:expr) => { ... };
}
Expand description
Construct a Daml value.
This macro provide a concise DSL for constructing an DamlValue
which can be used in the creation of contracts
and the exercising of choices.
§Syntax
A Daml record
is a map of label
to value
. A label
is always an identifier. A value
can be
a literal
, an identifier
, an expression
, a list
, an optional
, a variant
or a nested record
.
The macro always creates a DamlValue
enum which may be of any allowed enum variant. Typically a DamlRecord
is being constructed and so a DamlValue::Record
is produced.
Daml value pseudo-BNF grammar:
DamlValue ::= '{' ( label ':' DamlValue ',' )* '}' // Record
| '[' ( DamlValue ',' )* ']' // List
| '{' '=>' variant DamlValue '}' // Variant
| '{' '?=' DamlValue '}' // Optional (Some)
| '{' '?!' '}' // Optional (None)
| identifier ('::' type)? // String identifier
| literal ('::' type)? // String literal
| (expression) ('::' type)? // DamlValue expression
Note that this syntax is not whitespace sensitive.
The supported optional type
specifiers are:
code | name | type | example |
---|---|---|---|
p | party | DamlValue::Party | "Alice"::p |
c | contract id | DamlValue::ContractId | "#1:1"::c |
d | date | DamlValue::Date | "2019-01-01"::d |
t | timestamp | DamlValue::Timestamp | "2019-01-01T01:23:45Z"::t |
String literal used without a type specifier are assumed to be DamlValue::Text
therefore type specifiers are
only required for DamlValue::Party
(::p
) and DamlValue::ContractId
(::c
).
§Limitations
Data values passed as expressions (as opposed to simple literal values or identifiers) must be placed inside parentheses.
For example you may specify my_party_name_str::p
where my_party_name_str
is the identifier of an
in-scope variable containing a &str but you may not specify get_party_name_str()::p
where get_party_name_str()
is a function (and therefore an expression).
To support such cases either use (get_party_name_str())::p
or provide a DamlValue
DamlValue::new_party(get_party_name_str())
.
There is currently no support for DamlValue::Map
, DamlValue::GenMap
or DamlValue::Enum
.
§Examples
let value = daml_value![
// the DamlValue being created is a DamlValue::Record
{
// party is DamlValue::Party specified as a literal with a type suffix
party: "Alice"::p,
// a nested DamlValue::Record
trade: {
// a literal DamlValue::Int64
trade_id: 123,
// counterparty is DamlValue::Party, provided as an expression (note the outer
// braces here)
counterparty: (DamlValue::new_party("B".to_owned() + "ob")),
// trader is a DamlValue::Party literal built from an expression
trader: ("Ali".to_owned() + "ce")::p,
// trade_details is a DamlValue::Variant specifying SimpleDetails which contains
// a nested DamlValue::Record)
trade_details: {=>SimpleDetails {
// ticker is a String without type suffix and so becomes a
// DamlValue::Text
ticker: "GOOG",
// prices is an DamlValue::Optional which is Some(DamlValue::List(...))
prices: {?=[1231.54, 1234.85, 1237.92]},
// description is an DamlValue::Optional which is None
description: {?!},
// side is a DamlValue::Variant specifying Buy which contains
// a DamlValue::Text
side: {=>Buy "MarketOrder"}
}
}
}
}
];