daml_macro

Macro daml_value

Source
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:

codenametypeexample
ppartyDamlValue::Party"Alice"::p
ccontract idDamlValue::ContractId"#1:1"::c
ddateDamlValue::Date"2019-01-01"::d
ttimestampDamlValue::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"}
                }
            }
        }
    }
];