candid-core 0.1.0-beta.3

Canonical runtime Contract graph projection for Candid DID interfaces
Documentation
use candid_core::{compile_did, Actor, TypeNode};
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
    let compilation = compile_did(
        r#"
        /// A recursive value that remains finite in the Contract graph.
        type List = opt record {
          /// The current item.
          head: nat;
          /// The rest of the list.
          tail: List;
        };

        /// A small service used by the walkthrough.
        service : {
          /// Return the supplied list.
          echo: (input: List) -> (output: List) query;
        };
        "#,
    )?;

    let contract = compilation.contract();
    println!("contract identity: {}", contract.contract_id());
    println!("interface identity: {:?}", contract.interface_id());
    println!("canonical type nodes: {}", contract.types().len());

    let Some(Actor::Service { service }) = contract.actor() else {
        return Err("walkthrough expected a service actor".into());
    };
    let TypeNode::Service { methods } = &contract.types()[*service as usize] else {
        return Err("actor did not reference a service node".into());
    };
    for method in methods {
        let TypeNode::Func {
            args,
            results,
            mode,
        } = &contract.types()[method.function as usize]
        else {
            return Err("service method did not reference a function node".into());
        };
        println!(
            "method {} (wire id {}): {:?}, {} argument(s), {} result(s)",
            method.name,
            method.id,
            mode,
            args.len(),
            results.len()
        );
    }

    let source_info = compilation
        .source_info()
        .ok_or("source provenance was not requested")?;
    println!(
        "provenance: {} source(s), {} documented field occurrence(s), {} named function value(s)",
        source_info.sources().len(),
        source_info
            .field_labels()
            .iter()
            .filter(|field| !field.docs.is_empty())
            .count(),
        source_info.function_arguments().len()
    );

    println!("\nCanonical Contract JSON:\n{}", contract.to_json_pretty()?);
    Ok(())
}