homestar_invocation/task/instruction/input/
parse.rs

1use super::Args;
2use crate::error::InputParseError;
3
4/// Parsed [Args] consisting of [Inputs] for execution flows, as well as an
5/// optional function name/definition.
6///
7/// TODO: Extend via enumeration for singular objects/values.
8///
9/// [Inputs]: super::Input
10#[derive(Clone, Debug, PartialEq)]
11pub struct Parsed<T> {
12    args: Args<T>,
13    fun: Option<String>,
14}
15
16impl<T> Parsed<T> {
17    /// Initiate [Parsed] data structure with only [Args].
18    pub fn with(args: Args<T>) -> Self {
19        Parsed { args, fun: None }
20    }
21
22    /// Initiate [Parsed] data structure with a function name and
23    /// [Args].
24    pub fn with_fn(fun: String, args: Args<T>) -> Self {
25        Parsed {
26            args,
27            fun: Some(fun),
28        }
29    }
30
31    /// Parsed arguments.
32    pub fn args(&self) -> &Args<T> {
33        &self.args
34    }
35
36    /// Turn [Parsed] structure into owned [Args].
37    pub fn into_args(self) -> Args<T> {
38        self.args
39    }
40
41    /// Parsed function named.
42    pub fn fun(&self) -> Option<String> {
43        self.fun.as_ref().map(|f| f.to_string())
44    }
45}
46
47impl<T> From<Parsed<T>> for Args<T> {
48    fn from(apply: Parsed<T>) -> Self {
49        apply.args
50    }
51}
52
53/// Interface for [Instruction] implementations, relying on `homestore-core`
54/// to implement custom parsing specifics.
55///
56/// # Example
57///
58/// ```
59/// use homestar_invocation::{
60///     task::{
61///         instruction::{Ability, Args, Input, Parse},
62///         Instruction,
63///     },
64///     Unit,
65///  };
66/// use libipld::Ipld;
67/// use url::Url;
68///
69/// let wasm = "bafkreihxcyjgyrz437ewzi7md55uqt2zf6yr3zn7xrfi4orc34xdc5jgrm".to_string();
70/// let resource = Url::parse(format!("ipfs://{wasm}").as_str()).unwrap();
71///
72/// let inst = Instruction::unique(
73///     resource,
74///     Ability::from("wasm/run"),
75///     Input::<Unit>::Ipld(Ipld::List(vec![Ipld::Bool(true)]))
76/// );
77///
78/// let parsed = inst.input().parse().unwrap();
79///
80/// // turn into Args for invocation:
81/// let args: Args<Unit> = parsed.try_into().unwrap();
82/// ```
83///
84/// [Instruction]: crate::task::Instruction
85pub trait Parse<T> {
86    /// Function returning [Parsed] structure for execution/invocation.
87    ///
88    /// Note: meant to come before the `resolve` step
89    /// during runtime execution.
90    fn parse(&self) -> Result<Parsed<T>, InputParseError<T>>;
91}