homestar_invocation/task/instruction/
ability.rs1use crate::{Error, Unit};
7use libipld::{serde::from_ipld, Ipld};
8use serde::{Deserialize, Serialize};
9use std::{borrow::Cow, fmt};
10
11#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
40#[repr(transparent)]
41pub struct Ability(String);
42
43impl fmt::Display for Ability {
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 write!(f, "{}", self.0)
46 }
47}
48
49impl<'a> From<&'a str> for Ability {
50 fn from(ability: &'a str) -> Ability {
51 Ability(ability.trim().to_lowercase())
52 }
53}
54
55impl From<String> for Ability {
56 fn from(ability: String) -> Ability {
57 Ability::from(ability.as_str())
58 }
59}
60
61impl From<Ability> for Ipld {
62 fn from(ability: Ability) -> Ipld {
63 ability.0.into()
64 }
65}
66
67impl TryFrom<Ipld> for Ability {
68 type Error = Error<Unit>;
69
70 fn try_from(ipld: Ipld) -> Result<Self, Self::Error> {
71 let ability = from_ipld::<String>(ipld)?;
72 Ok(Ability::from(ability))
73 }
74}
75
76impl<'a> From<Ability> for Cow<'a, Ability> {
77 fn from(ability: Ability) -> Self {
78 Cow::Owned(ability)
79 }
80}
81
82impl<'a> From<&'a Ability> for Cow<'a, Ability> {
83 fn from(ability: &'a Ability) -> Self {
84 Cow::Borrowed(ability)
85 }
86}
87
88#[cfg(test)]
89mod test {
90 use super::*;
91
92 #[test]
93 fn ipld_roundtrip() {
94 let ability = Ability::from("wasm/run");
95 let ipld = Ipld::from(ability.clone());
96
97 assert_eq!(ipld, Ipld::String("wasm/run".to_string()));
98 assert_eq!(ability, ipld.try_into().unwrap())
99 }
100
101 #[test]
102 fn ser_de() {
103 let ability = Ability::from("wasm/run");
104 let ser = serde_json::to_string(&ability).unwrap();
105 let de = serde_json::from_str(&ser).unwrap();
106
107 assert_eq!(ability, de);
108 }
109}