use crate::{Error, Unit};
use libipld::{serde::from_ipld, Ipld};
use serde::{Deserialize, Serialize};
use std::{borrow::Cow, fmt};
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
#[repr(transparent)]
pub struct Ability(String);
impl fmt::Display for Ability {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl<'a> From<&'a str> for Ability {
fn from(ability: &'a str) -> Ability {
Ability(ability.trim().to_lowercase())
}
}
impl From<String> for Ability {
fn from(ability: String) -> Ability {
Ability::from(ability.as_str())
}
}
impl From<Ability> for Ipld {
fn from(ability: Ability) -> Ipld {
ability.0.into()
}
}
impl TryFrom<Ipld> for Ability {
type Error = Error<Unit>;
fn try_from(ipld: Ipld) -> Result<Self, Self::Error> {
let ability = from_ipld::<String>(ipld)?;
Ok(Ability::from(ability))
}
}
impl<'a> From<Ability> for Cow<'a, Ability> {
fn from(ability: Ability) -> Self {
Cow::Owned(ability)
}
}
impl<'a> From<&'a Ability> for Cow<'a, Ability> {
fn from(ability: &'a Ability) -> Self {
Cow::Borrowed(ability)
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn ipld_roundtrip() {
let ability = Ability::from("wasm/run");
let ipld = Ipld::from(ability.clone());
assert_eq!(ipld, Ipld::String("wasm/run".to_string()));
assert_eq!(ability, ipld.try_into().unwrap())
}
#[test]
fn ser_de() {
let ability = Ability::from("wasm/run");
let ser = serde_json::to_string(&ability).unwrap();
let de = serde_json::from_str(&ser).unwrap();
assert_eq!(ability, de);
}
}