1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
use nom::branch::alt; use nom::combinator::{map, opt}; use nom::multi::many0; use nom::sequence::delimited; use nom::IResult; use crate::basic::Separator; use crate::definition::{ Const, ConstRef, Enum, EnumRef, Exception, ExceptionRef, Service, ServiceRef, Struct, StructRef, Typedef, TypedefRef, Union, UnionRef, }; use crate::header::{CppInclude, CppIncludeRef, Include, IncludeRef, Namespace, NamespaceRef}; use crate::Parser; #[derive(PartialEq, Debug, Clone, Default)] pub struct DocumentRef<'a> { pub includes: Vec<IncludeRef<'a>>, pub cpp_includes: Vec<CppIncludeRef<'a>>, pub namespaces: Vec<NamespaceRef<'a>>, pub typedefs: Vec<TypedefRef<'a>>, pub consts: Vec<ConstRef<'a>>, pub enums: Vec<EnumRef<'a>>, pub structs: Vec<StructRef<'a>>, pub unions: Vec<UnionRef<'a>>, pub exceptions: Vec<ExceptionRef<'a>>, pub services: Vec<ServiceRef<'a>>, } impl<'a> Parser<'a> for DocumentRef<'a> { fn parse(input: &'a str) -> IResult<&'a str, Self> { let mut target = Self::default(); let includes = &mut target.includes; let cpp_includes = &mut target.cpp_includes; let namespaces = &mut target.namespaces; let typedefs = &mut target.typedefs; let consts = &mut target.consts; let enums = &mut target.enums; let structs = &mut target.structs; let unions = &mut target.unions; let exceptions = &mut target.exceptions; let services = &mut target.services; let (remains, _) = many0(delimited( opt(Separator::parse), alt(( map(IncludeRef::parse, |i| includes.push(i)), map(CppIncludeRef::parse, |i| cpp_includes.push(i)), map(NamespaceRef::parse, |i| namespaces.push(i)), map(TypedefRef::parse, |i| typedefs.push(i)), map(ConstRef::parse, |i| consts.push(i)), map(EnumRef::parse, |i| enums.push(i)), map(StructRef::parse, |i| structs.push(i)), map(UnionRef::parse, |i| unions.push(i)), map(ExceptionRef::parse, |i| exceptions.push(i)), map(ServiceRef::parse, |i| services.push(i)), )), opt(Separator::parse), ))(input)?; Ok((remains, target)) } } #[derive(PartialEq, Debug, Clone, Default)] pub struct Document { pub includes: Vec<Include>, pub cpp_includes: Vec<CppInclude>, pub namespaces: Vec<Namespace>, pub typedefs: Vec<Typedef>, pub consts: Vec<Const>, pub enums: Vec<Enum>, pub structs: Vec<Struct>, pub unions: Vec<Union>, pub exceptions: Vec<Exception>, pub services: Vec<Service>, } impl<'a> From<DocumentRef<'a>> for Document { fn from(r: DocumentRef<'a>) -> Self { Self { includes: r.includes.into_iter().map(Into::into).collect(), cpp_includes: r.cpp_includes.into_iter().map(Into::into).collect(), namespaces: r.namespaces.into_iter().map(Into::into).collect(), typedefs: r.typedefs.into_iter().map(Into::into).collect(), consts: r.consts.into_iter().map(Into::into).collect(), enums: r.enums.into_iter().map(Into::into).collect(), structs: r.structs.into_iter().map(Into::into).collect(), unions: r.unions.into_iter().map(Into::into).collect(), exceptions: r.exceptions.into_iter().map(Into::into).collect(), services: r.services.into_iter().map(Into::into).collect(), } } } impl<'a> Parser<'a> for Document { fn parse(input: &'a str) -> IResult<&'a str, Self> { DocumentRef::parse(input).map(|(remains, parsed)| (remains, parsed.into())) } } #[cfg(test)] mod tests { use crate::basic::LiteralRef; use super::*; #[test] fn test_document() { let expected = DocumentRef { includes: vec![IncludeRef::from(LiteralRef::from("another.thrift"))], ..Default::default() }; assert_eq!( DocumentRef::parse("include 'another.thrift'").unwrap().1, expected ); } }