#![doc(html_root_url = "https://docs.rs/syn-codegen/0.4.2")]
use indexmap::IndexMap;
use semver::Version;
#[cfg(feature = "serde")]
use serde::de::{Deserialize, Deserializer};
#[cfg(feature = "serde")]
use serde_derive::{Deserialize, Serialize};
use std::collections::{BTreeMap, BTreeSet};
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Definitions {
pub version: Version,
pub types: Vec<Node>,
pub tokens: BTreeMap<String, String>,
}
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Node {
pub ident: String,
pub features: Features,
#[cfg_attr(
feature = "serde",
serde(
flatten,
skip_serializing_if = "is_private",
deserialize_with = "private_if_absent"
)
)]
pub data: Data,
#[cfg_attr(
feature = "serde",
serde(skip_serializing_if = "is_true", default = "bool_true")
)]
pub exhaustive: bool,
}
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Data {
Private,
#[cfg_attr(feature = "serde", serde(rename = "fields"))]
Struct(Fields),
#[cfg_attr(feature = "serde", serde(rename = "variants"))]
Enum(Variants),
}
pub type Fields = IndexMap<String, Type>;
pub type Variants = IndexMap<String, Vec<Type>>;
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(rename_all = "lowercase")
)]
pub enum Type {
Syn(String),
Std(String),
#[cfg_attr(feature = "serde", serde(rename = "proc_macro2"))]
Ext(String),
Token(String),
Group(String),
Punctuated(Punctuated),
Option(Box<Type>),
Box(Box<Type>),
Vec(Box<Type>),
Tuple(Vec<Type>),
}
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Punctuated {
pub element: Box<Type>,
pub punct: String,
}
#[derive(Clone, Debug, Default, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Features {
pub any: BTreeSet<String>,
}
#[cfg(feature = "serde")]
fn is_private(data: &Data) -> bool {
match data {
Data::Private => true,
Data::Struct(_) | Data::Enum(_) => false,
}
}
#[cfg(feature = "serde")]
fn private_if_absent<'de, D>(deserializer: D) -> Result<Data, D::Error>
where
D: Deserializer<'de>,
{
let option = Option::deserialize(deserializer)?;
Ok(option.unwrap_or(Data::Private))
}
#[cfg(feature = "serde")]
fn is_true(b: &bool) -> bool {
*b
}
#[cfg(feature = "serde")]
fn bool_true() -> bool {
true
}