#[macro_use]
extern crate nom;
mod parser;
use std::ops::Range;
use parser::file_descriptor;
#[derive(Debug, Clone, Copy)]
pub enum Syntax {
Proto2,
Proto3,
}
impl Default for Syntax {
fn default() -> Syntax {
Syntax::Proto2
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum Rule {
Optional,
Repeated,
Required,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum FieldType {
Int32,
Int64,
Uint32,
Uint64,
Sint32,
Sint64,
Bool,
Fixed64,
Sfixed64,
Double,
String,
Bytes,
Fixed32,
Sfixed32,
Float,
MessageOrEnum(String),
Map(Box<(FieldType, FieldType)>),
Group(Vec<Field>),
}
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
pub struct Field {
pub name: String,
pub rule: Rule,
pub typ: FieldType,
pub number: i32,
pub default: Option<String>,
pub packed: Option<bool>,
pub deprecated: bool,
}
#[derive(Debug, Clone, Default)]
pub struct Message {
pub name: String,
pub fields: Vec<Field>,
pub oneofs: Vec<OneOf>,
pub reserved_nums: Vec<Range<i32>>,
pub reserved_names: Vec<String>,
pub messages: Vec<Message>,
pub enums: Vec<Enumeration>,
}
#[derive(Debug, Clone)]
pub struct EnumValue {
pub name: String,
pub number: i32,
}
#[derive(Debug, Clone)]
pub struct Enumeration {
pub name: String,
pub values: Vec<EnumValue>,
}
#[derive(Debug, Clone, Default)]
pub struct OneOf {
pub name: String,
pub fields: Vec<Field>,
}
#[derive(Debug, Clone)]
pub struct Extension {
pub extendee: String,
pub field: Field,
}
#[derive(Debug, Default, Clone)]
pub struct FileDescriptor {
pub import_paths: Vec<String>,
pub package: String,
pub syntax: Syntax,
pub messages: Vec<Message>,
pub enums: Vec<Enumeration>,
pub extensions: Vec<Extension>,
}
impl FileDescriptor {
pub fn parse<S: AsRef<[u8]>>(file: S) -> Result<Self, ::nom::IError> {
let file = file.as_ref();
match file_descriptor(file) {
::nom::IResult::Done(unparsed, r) => {
if !unparsed.is_empty() {
Err(::nom::IError::Error(::nom::ErrorKind::NoneOf))
} else {
Ok(r)
}
}
o => o.to_full_result(),
}
}
}