mod group; mod map; mod message; mod oneof; mod scalar;
use std::fmt; use std::slice;
use anyhow::{bail, Error}; use proc_macro2::TokenStream; use quote::quote; use syn::punctuated::Punctuated; use syn::{Attribute, Expr, ExprLit, Lit, LitBool, LitInt, Meta, MetaNameValue, Token};
#[derive(Clone)] pubenum Field { /// A scalar field.
Scalar(scalar::Field), /// A message field.
Message(message::Field), /// A map field.
Map(map::Field), /// A oneof field.
Oneof(oneof::Field), /// A group field.
Group(group::Field),
}
impl Field { /// Creates a new `Field` from an iterator of field attributes. /// /// If the meta items are invalid, an error will be returned. /// If the field should be ignored, `None` is returned. pubfn new(attrs: Vec<Attribute>, inferred_tag: Option<u32>) -> Result<Option<Field>, Error> { let attrs = prost_attrs(attrs)?;
/// Creates a new oneof `Field` from an iterator of field attributes. /// /// If the meta items are invalid, an error will be returned. /// If the field should be ignored, `None` is returned. pubfn new_oneof(attrs: Vec<Attribute>) -> Result<Option<Field>, Error> { let attrs = prost_attrs(attrs)?;
// TODO: check for ignore attribute.
let field = iflet Some(field) = scalar::Field::new_oneof(&attrs)? {
Field::Scalar(field)
} elseiflet Some(field) = message::Field::new_oneof(&attrs)? {
Field::Message(field)
} elseiflet Some(field) = map::Field::new_oneof(&attrs)? {
Field::Map(field)
} elseiflet Some(field) = group::Field::new_oneof(&attrs)? {
Field::Group(field)
} else {
bail!("no type attribute for oneof field");
};
/// Returns a statement which encodes the field. pubfn encode(&self, ident: TokenStream) -> TokenStream { match *self {
Field::Scalar(ref scalar) => scalar.encode(ident),
Field::Message(ref message) => message.encode(ident),
Field::Map(ref map) => map.encode(ident),
Field::Oneof(ref oneof) => oneof.encode(ident),
Field::Group(ref group) => group.encode(ident),
}
}
/// Returns an expression which evaluates to the result of merging a decoded /// value into the field. pubfn merge(&self, ident: TokenStream) -> TokenStream { match *self {
Field::Scalar(ref scalar) => scalar.merge(ident),
Field::Message(ref message) => message.merge(ident),
Field::Map(ref map) => map.merge(ident),
Field::Oneof(ref oneof) => oneof.merge(ident),
Field::Group(ref group) => group.merge(ident),
}
}
/// Returns an expression which evaluates to the encoded length of the field. pubfn encoded_len(&self, ident: TokenStream) -> TokenStream { match *self {
Field::Scalar(ref scalar) => scalar.encoded_len(ident),
Field::Map(ref map) => map.encoded_len(ident),
Field::Message(ref msg) => msg.encoded_len(ident),
Field::Oneof(ref oneof) => oneof.encoded_len(ident),
Field::Group(ref group) => group.encoded_len(ident),
}
}
/// Returns a statement which clears the field. pubfn clear(&self, ident: TokenStream) -> TokenStream { match *self {
Field::Scalar(ref scalar) => scalar.clear(ident),
Field::Message(ref message) => message.clear(ident),
Field::Map(ref map) => map.clear(ident),
Field::Oneof(ref oneof) => oneof.clear(ident),
Field::Group(ref group) => group.clear(ident),
}
}
/// Parses a string into a field label. /// If the string doesn't match a field label, `None` is returned. fn from_attr(attr: &Meta) -> Option<Label> { iflet Meta::Path(ref path) = *attr { for &label in Label::variants() { if path.is_ident(label.as_str()) { return Some(label);
}
}
}
None
}
}
/// Get the items belonging to the 'prost' list attribute, e.g. `#[prost(foo, bar="baz")]`. fn prost_attrs(attrs: Vec<Attribute>) -> Result<Vec<Meta>, Error> { letmut result = Vec::new(); for attr in attrs.iter() { iflet Meta::List(meta_list) = &attr.meta { if meta_list.path.is_ident("prost") {
result.extend(
meta_list
.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)?
.into_iter(),
)
}
}
}
Ok(result)
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.