zephyrus-macros 0.11.0

Procedural macros used by Zephyrus
Documentation
use std::marker::PhantomData;

use darling::{FromMeta, export::NestedMeta};
use proc_macro2::Span;
use quote::ToTokens;
use syn::{Token, parse::{Parse, ParseStream}};

pub struct Tuple2<K, V, D = Token![=]>(pub K, pub V, PhantomData<D>);

impl<K, V, D> Tuple2<K, V, D> {
    pub fn new(k: K, v: V) -> Self {
        Self(k, v, PhantomData)
    }
}

impl<K, V, D> Parse for Tuple2<K, V, D>
where
    K: Parse,
    V: Parse,
    D: Parse
{
    fn parse(input: ParseStream) -> syn::Result<Self> {
        let k = input.parse()?;
        let _: D = input.parse()?;
        let v = input.parse()?;

        Ok(Self::new(k, v))
    }
}

impl<K, V, D> FromMeta for Tuple2<K, V, D> 
where
    K: FromMeta,
    V: FromMeta,
{
    fn from_list(items: &[NestedMeta]) -> darling::Result<Self> {
        match items {
            [a, b] => 
                Ok(Self(K::from_nested_meta(a)?, V::from_nested_meta(b)?, PhantomData)),
            _ => Err(darling::Error::unsupported_format("2 item tuple").with_span(&Span::call_site()))
        }
    }
}

impl<K, V, D> ToTokens for Tuple2<K, V, D>
where
    K: ToTokens,
    V: ToTokens
{
    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
        let k = &self.0;
        let v = &self.1;
        tokens.extend(quote::quote!((#k, #v)))
    }
}