touchportal-sdk 0.0.1

SDK for authoring TouchPortal plugins in Rust
Documentation
pub trait TouchPortalToString {
    fn stringify(&self) -> String;
}

impl<T: TouchPortalToString + ?Sized> TouchPortalToString for &T {
    fn stringify(&self) -> String {
        T::stringify(*self)
    }
}

impl TouchPortalToString for String {
    fn stringify(&self) -> String {
        self.clone()
    }
}

impl TouchPortalToString for str {
    fn stringify(&self) -> String {
        self.to_string()
    }
}

impl TouchPortalToString for f64 {
    fn stringify(&self) -> String {
        self.to_string()
    }
}

impl TouchPortalToString for bool {
    fn stringify(&self) -> String {
        match self {
            true => String::from("On"),
            false => String::from("Off"),
        }
    }
}

pub trait TouchPortalFromStr: Sized {
    fn destringify(s: &str) -> eyre::Result<Self>;
}

impl TouchPortalFromStr for String {
    fn destringify(v: &str) -> eyre::Result<Self> {
        Ok(v.to_string())
    }
}

impl TouchPortalFromStr for f64 {
    fn destringify(v: &str) -> eyre::Result<Self> {
        Ok(v.parse()?)
    }
}

impl TouchPortalFromStr for bool {
    fn destringify(v: &str) -> eyre::Result<Self> {
        match v {
            "On" => Ok(true),
            "Off" => Ok(false),
            other => eyre::bail!("TouchPortal does not use {other} for switch values"),
        }
    }
}

pub mod serde_tp_stringly {
    use serde::{Serialize, Serializer};

    pub fn serialize<S, T>(t: &T, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
        T: super::TouchPortalToString,
    {
        T::stringify(t).serialize(serializer)
    }

    pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error>
    where
        D: ::serde::Deserializer<'de>,
        T: super::TouchPortalFromStr,
    {
        use ::serde::de::Visitor;

        struct V<S>(std::marker::PhantomData<fn() -> S>);

        impl<'de, S> Visitor<'de> for V<S>
        where
            S: super::TouchPortalFromStr,
        {
            type Value = S;

            fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                formatter.write_str("a string representing an S")
            }

            fn visit_str<E>(self, v: &str) -> Result<S, E>
            where
                E: ::serde::de::Error,
            {
                S::destringify(v).map_err(::serde::de::Error::custom)
            }
        }

        deserializer.deserialize_str(V::<T>(Default::default()))
    }
}

mod incoming;
pub use incoming::*;

mod outgoing;
pub use outgoing::*;