use std::{borrow::Cow, collections::HashSet};
use once_cell::sync::Lazy;
pub struct Field<'a> {
name: &'a str,
rename: Option<&'a str>,
type_spec: &'a str,
}
impl<'a> Field<'a> {
pub fn new(name: &'a str, type_spec: &'a str) -> Self {
Field {
name,
type_spec,
rename: None,
}
}
pub fn add_rename(&mut self, name: &'a str) {
self.rename = Some(name);
}
fn name(&self) -> Cow<'a, str> {
if KEYWORDS.contains(self.name) {
return Cow::Owned(format!("{}_", self.name));
}
if self.name == "_" {
return Cow::Borrowed("__underscore");
}
Cow::Borrowed(self.name)
}
fn rename(&self) -> Option<&'a str> {
if let Some(rename) = self.rename {
return Some(rename);
}
if KEYWORDS.contains(self.name) || self.name == "_" {
return Some(self.name);
}
None
}
}
impl std::fmt::Display for Field<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(rename) = self.rename() {
writeln!(f, r#"#[cynic(rename = "{}")]"#, rename)?;
}
writeln!(f, "pub {}: {},", self.name(), self.type_spec)
}
}
static KEYWORDS: Lazy<HashSet<&'static str>> = Lazy::new(|| {
let mut set = HashSet::new();
set.insert("as");
set.insert("break");
set.insert("const");
set.insert("continue");
set.insert("else");
set.insert("enum");
set.insert("false");
set.insert("fn");
set.insert("for");
set.insert("if");
set.insert("impl");
set.insert("in");
set.insert("let");
set.insert("loop");
set.insert("match");
set.insert("mod");
set.insert("move");
set.insert("mut");
set.insert("pub");
set.insert("ref");
set.insert("return");
set.insert("static");
set.insert("struct");
set.insert("trait");
set.insert("true");
set.insert("type");
set.insert("unsafe");
set.insert("use");
set.insert("where");
set.insert("while");
set.insert("async");
set.insert("await");
set.insert("dyn");
set.insert("abstract");
set.insert("become");
set.insert("box");
set.insert("do");
set.insert("final");
set.insert("macro");
set.insert("override");
set.insert("priv");
set.insert("typeof");
set.insert("unsized");
set.insert("virtual");
set.insert("yield");
set.insert("try");
set.insert("super");
set.insert("self");
set.insert("Self");
set.insert("extern");
set.insert("crate");
set
});