ascom-alpaca 1.0.0-beta.10

Rust implementation of the ASCOM Alpaca API for astronomy devices
Documentation
use serde::de::{DeserializeSeed, Error, IntoDeserializer, MapAccess, SeqAccess, Visitor};
use serde::{Deserialize, Deserializer};
use std::marker::PhantomData;

struct DeviceStateDeserializer<D>(D);

impl<'de, V: Visitor<'de>> Visitor<'de> for DeviceStateDeserializer<V> {
    type Value = V::Value;

    fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        formatter.write_str("a sequence")
    }

    fn visit_seq<S: SeqAccess<'de>>(self, seq: S) -> Result<Self::Value, S::Error> {
        self.0.visit_map(EntryMapAccess {
            seq,
            stored_value: serde_json::Value::Null,
        })
    }
}

struct EntryMapAccess<A> {
    seq: A,
    stored_value: serde_json::Value,
}

impl<'de, A: SeqAccess<'de>> MapAccess<'de> for EntryMapAccess<A> {
    type Error = A::Error;

    fn next_key_seed<K: DeserializeSeed<'de>>(
        &mut self,
        seed: K,
    ) -> Result<Option<K::Value>, Self::Error> {
        Ok(self.next_entry_seed(seed, PhantomData)?.map(|(k, v)| {
            self.stored_value = v;
            k
        }))
    }

    fn next_value_seed<V: DeserializeSeed<'de>>(
        &mut self,
        seed: V,
    ) -> Result<V::Value, Self::Error> {
        seed.deserialize(self.stored_value.take().into_deserializer())
            .map_err(Error::custom)
    }

    fn next_entry_seed<K: DeserializeSeed<'de>, V: DeserializeSeed<'de>>(
        &mut self,
        name: K,
        value: V,
    ) -> Result<Option<(K::Value, V::Value)>, Self::Error> {
        struct Entry<K, V> {
            name: K,
            value: V,
        }

        impl<'de, K: DeserializeSeed<'de>, V: DeserializeSeed<'de>> DeserializeSeed<'de> for Entry<K, V> {
            type Value = (K::Value, V::Value);

            fn deserialize<D: Deserializer<'de>>(
                self,
                deserializer: D,
            ) -> Result<Self::Value, D::Error> {
                deserializer.deserialize_map(self)
            }
        }

        impl<'de, K: DeserializeSeed<'de>, V: DeserializeSeed<'de>> Visitor<'de> for Entry<K, V> {
            type Value = (K::Value, V::Value);

            fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                formatter.write_str("a {Name, Value} object")
            }

            fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
                #[derive(Deserialize)]
                #[serde(field_identifier)]
                enum Field {
                    Name,
                    Value,
                }

                struct FieldState<'de, S: DeserializeSeed<'de>> {
                    name: &'static str,
                    seed: Option<S>,
                    value: Option<S::Value>,
                }

                impl<'de, S: DeserializeSeed<'de>> DeserializeSeed<'de> for &'_ mut FieldState<'de, S> {
                    type Value = ();

                    fn deserialize<D: Deserializer<'de>>(
                        self,
                        deserializer: D,
                    ) -> Result<Self::Value, D::Error> {
                        let seed = self
                            .seed
                            .take()
                            .ok_or_else(|| Error::duplicate_field(self.name))?;
                        self.value = Some(seed.deserialize(deserializer)?);
                        Ok(())
                    }
                }

                impl<'de, S: DeserializeSeed<'de>> FieldState<'de, S> {
                    const fn new(name: &'static str, seed: S) -> Self {
                        Self {
                            name,
                            seed: Some(seed),
                            value: None,
                        }
                    }

                    fn finish<E: Error>(self) -> Result<S::Value, E> {
                        self.value.ok_or_else(|| Error::missing_field(self.name))
                    }
                }

                let mut name = FieldState::new("Name", self.name);
                let mut value = FieldState::new("Value", self.value);

                while let Some(field) = map.next_key::<Field>()? {
                    match field {
                        Field::Name => map.next_value_seed(&mut name),
                        Field::Value => map.next_value_seed(&mut value),
                    }?;
                }

                Ok((name.finish()?, value.finish()?))
            }
        }

        self.seq.next_element_seed(Entry { name, value })
    }
}

impl<'de, D: Deserializer<'de>> Deserializer<'de> for DeviceStateDeserializer<D> {
    type Error = D::Error;

    fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
        self.0.deserialize_seq(DeviceStateDeserializer(visitor))
    }

    serde::forward_to_deserialize_any![
        char
        bool
        i8
        i16
        i32
        i64
        u8
        u16
        u32
        u64
        f32
        f64
        str
        string
        bytes
        byte_buf
        option
        unit
        unit_struct
        newtype_struct
        seq
        tuple
        tuple_struct
        map
        struct
        enum
        identifier
        ignored_any
    ];
}

pub(crate) struct TimestampedDeviceStateRepr<T>(T);

impl<'de, T: Deserialize<'de>> Deserialize<'de> for TimestampedDeviceStateRepr<T> {
    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        T::deserialize(DeviceStateDeserializer(deserializer)).map(Self)
    }
}

impl<T> TimestampedDeviceStateRepr<T> {
    pub(crate) fn into_inner(self) -> T {
        self.0
    }
}