homestar_invocation/
unit.rs

1//! Exported `unit` type for generic type conversions within
2//! [Tasks], [Inputs], and around [Invocations].
3//!
4//! [Tasks]: crate::Task
5//! [Inputs]: crate::task::instruction::Input
6//! [Invocations]: crate::Invocation
7
8use crate::{
9    error::InputParseError,
10    task::instruction::{Args, Input, Parse, Parsed},
11    Error,
12};
13use libipld::Ipld;
14use serde::{Deserialize, Serialize};
15
16/// Unit type, which allows only one value (and thusly holds
17/// no information). Essentially a wrapper over `()`, but one we control.
18#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
19pub struct Unit;
20
21impl From<Unit> for Ipld {
22    fn from(_unit: Unit) -> Self {
23        Ipld::Null
24    }
25}
26
27impl From<Ipld> for Unit {
28    fn from(_ipld: Ipld) -> Self {
29        Unit
30    }
31}
32
33// Default implementation.
34impl Parse<Unit> for Input<Unit> {
35    fn parse(&self) -> Result<Parsed<Unit>, InputParseError<Unit>> {
36        let args = match Ipld::from(self.to_owned()) {
37            Ipld::List(v) => Ipld::List(v).try_into()?,
38            ipld => Args::new(vec![ipld.try_into()?]),
39        };
40
41        Ok(Parsed::with(args))
42    }
43}
44
45impl From<Error<String>> for InputParseError<Unit> {
46    fn from(err: Error<String>) -> Self {
47        InputParseError::Invocation(err.into())
48    }
49}
50
51#[cfg(test)]
52mod test {
53    use super::*;
54
55    #[test]
56    fn ser_de() {
57        let unit = Unit;
58        let ser = serde_json::to_string(&unit).unwrap();
59        let de = serde_json::from_str(&ser).unwrap();
60
61        assert_eq!(unit, de);
62    }
63}