Some docs

This commit is contained in:
Richard Dodd 2018-09-29 15:06:23 +01:00
parent 3f0f739e17
commit da65fe5a52
4 changed files with 35 additions and 1 deletions

View File

@ -6,24 +6,36 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
//! A serde ast, parsed from the syn ast and ready for codegen.
use internals::attr; use internals::attr;
use internals::check; use internals::check;
use internals::{Ctxt, Derive}; use internals::{Ctxt, Derive};
use syn; use syn;
use syn::punctuated::Punctuated; use syn::punctuated::Punctuated;
/// A source data structure annotated with `#[derive(Derialize)]` and/or `#[derive(Deserialize)]`,
/// parsed into an internal representation.
pub struct Container<'a> { pub struct Container<'a> {
/// The struct or enum name (without generics).
pub ident: syn::Ident, pub ident: syn::Ident,
/// Attributes on the structure, parsed for serde.
pub attrs: attr::Container, pub attrs: attr::Container,
/// The contents of the struct or enum.
pub data: Data<'a>, pub data: Data<'a>,
/// Any generics on the struct or enum.
pub generics: &'a syn::Generics, pub generics: &'a syn::Generics,
} }
/// The fields of a struct or enum.
///
/// Analagous to `syn::Data`.
pub enum Data<'a> { pub enum Data<'a> {
Enum(Vec<Variant<'a>>), Enum(Vec<Variant<'a>>),
Struct(Style, Vec<Field<'a>>), Struct(Style, Vec<Field<'a>>),
} }
/// A variant of an enum.
pub struct Variant<'a> { pub struct Variant<'a> {
pub ident: syn::Ident, pub ident: syn::Ident,
pub attrs: attr::Variant, pub attrs: attr::Variant,
@ -31,6 +43,7 @@ pub struct Variant<'a> {
pub fields: Vec<Field<'a>>, pub fields: Vec<Field<'a>>,
} }
/// A variant of a struct.
pub struct Field<'a> { pub struct Field<'a> {
pub member: syn::Member, pub member: syn::Member,
pub attrs: attr::Field, pub attrs: attr::Field,
@ -40,13 +53,18 @@ pub struct Field<'a> {
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub enum Style { pub enum Style {
/// Named fields.
Struct, Struct,
/// Many unnamed fields.
Tuple, Tuple,
/// One unnamed field.
Newtype, Newtype,
/// No fields.
Unit, Unit,
} }
impl<'a> Container<'a> { impl<'a> Container<'a> {
/// Convert the raw syn ast into a parsed container object, collecting errors in `cx`.
pub fn from_ast(cx: &Ctxt, item: &'a syn::DeriveInput, derive: Derive) -> Container<'a> { pub fn from_ast(cx: &Ctxt, item: &'a syn::DeriveInput, derive: Derive) -> Container<'a> {
let mut attrs = attr::Container::from_ast(cx, item); let mut attrs = attr::Container::from_ast(cx, item);

View File

@ -106,7 +106,7 @@ impl Name {
} }
} }
/// Represents container (e.g. struct) attribute information /// Represents struct or enum attribute information.
pub struct Container { pub struct Container {
name: Name, name: Name,
transparent: bool, transparent: bool,

View File

@ -6,6 +6,9 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
//! Stuff to handle where the case of the source (e.g. `my-field`) is different to the
//! field/variant (e.g. `my_field`).
// See https://users.rust-lang.org/t/psa-dealing-with-warning-unused-import-std-ascii-asciiext-in-today-s-nightly/13726 // See https://users.rust-lang.org/t/psa-dealing-with-warning-unused-import-std-ascii-asciiext-in-today-s-nightly/13726
#[allow(deprecated, unused_imports)] #[allow(deprecated, unused_imports)]
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
@ -14,6 +17,7 @@ use std::str::FromStr;
use self::RenameRule::*; use self::RenameRule::*;
/// The different possible ways to change case of fields in a struct, or variants in an enum.
#[derive(PartialEq)] #[derive(PartialEq)]
pub enum RenameRule { pub enum RenameRule {
/// Don't apply a default rename rule. /// Don't apply a default rename rule.
@ -40,6 +44,7 @@ pub enum RenameRule {
} }
impl RenameRule { impl RenameRule {
/// Apply a renaming rule to an enum variant, returning the version expected in the source.
pub fn apply_to_variant(&self, variant: &str) -> String { pub fn apply_to_variant(&self, variant: &str) -> String {
match *self { match *self {
None | PascalCase => variant.to_owned(), None | PascalCase => variant.to_owned(),
@ -64,6 +69,7 @@ impl RenameRule {
} }
} }
/// Apply a renaming rule to a struct field, returning the version expected in the source.
pub fn apply_to_field(&self, field: &str) -> String { pub fn apply_to_field(&self, field: &str) -> String {
match *self { match *self {
None | LowerCase | SnakeCase => field.to_owned(), None | LowerCase | SnakeCase => field.to_owned(),

View File

@ -10,18 +10,27 @@ use std::cell::RefCell;
use std::fmt::Display; use std::fmt::Display;
use std::thread; use std::thread;
/// A type to collect errors together and format them.
///
/// Dropping this object will cause a panic. It must be consumed using `check`.
///
/// References can be shared since this type uses run-time exclusive mut checking.
#[derive(Default)] #[derive(Default)]
pub struct Ctxt { pub struct Ctxt {
// The contents will be set to `None` during checking. This is so that checking can be
// enforced.
errors: RefCell<Option<Vec<String>>>, errors: RefCell<Option<Vec<String>>>,
} }
impl Ctxt { impl Ctxt {
/// Create a new context object
pub fn new() -> Self { pub fn new() -> Self {
Ctxt { Ctxt {
errors: RefCell::new(Some(Vec::new())), errors: RefCell::new(Some(Vec::new())),
} }
} }
/// Add an error to the context object
pub fn error<T: Display>(&self, msg: T) { pub fn error<T: Display>(&self, msg: T) {
self.errors self.errors
.borrow_mut() .borrow_mut()
@ -30,6 +39,7 @@ impl Ctxt {
.push(msg.to_string()); .push(msg.to_string());
} }
/// Consume this object, producing a formatted error string if there are errors.
pub fn check(self) -> Result<(), String> { pub fn check(self) -> Result<(), String> {
let mut errors = self.errors.borrow_mut().take().unwrap(); let mut errors = self.errors.borrow_mut().take().unwrap();
match errors.len() { match errors.len() {