Created
January 31, 2023 20:30
-
-
Save kennykerr/c78c8e3263e5b6aa8e268015847899d8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use syn::{parse::*, *}; | |
mod keywords { | |
syn::custom_keyword!(interface); | |
} | |
#[derive(Debug)] | |
struct Module { | |
pub name: Ident, | |
pub members: Vec<ModuleMember>, | |
} | |
impl Parse for Module { | |
fn parse(input: ParseStream) -> Result<Self> { | |
input.parse::<Token![mod]>()?; | |
let name = input.parse::<Ident>()?; | |
let content; | |
braced!(content in input); | |
let mut members = Vec::new(); | |
while !content.is_empty() { | |
members.push(content.parse::<ModuleMember>()?); | |
} | |
Ok(Self { name, members }) | |
} | |
} | |
#[derive(Debug)] | |
enum ModuleMember { | |
Module(Module), | |
Interface(Interface), | |
} | |
impl Parse for ModuleMember { | |
fn parse(input: ParseStream) -> Result<Self> { | |
let lookahead = input.lookahead1(); | |
if lookahead.peek(Token![mod]) { | |
Ok(ModuleMember::Module(input.parse::<Module>()?)) | |
} else if lookahead.peek(keywords::interface) { | |
Ok(ModuleMember::Interface(input.parse::<Interface>()?)) | |
} else { | |
Err(lookahead.error()) | |
} | |
} | |
} | |
#[derive(Debug)] | |
struct Interface { | |
pub name: Ident, | |
pub methods: Vec<TraitItemMethod>, | |
} | |
impl Parse for Interface { | |
fn parse(input: ParseStream) -> Result<Self> { | |
input.parse::<keywords::interface>()?; | |
let name = input.parse::<Ident>()?; | |
let content; | |
braced!(content in input); | |
let mut methods = Vec::new(); | |
while !content.is_empty() { | |
methods.push(content.parse::<TraitItemMethod>()?); | |
} | |
Ok(Self { name, methods }) | |
} | |
} | |
fn main() { | |
let input = r#" | |
mod Things { | |
interface IThing { | |
fn Method(&self, p1: u8) -> f32; | |
} | |
} | |
"#; | |
let result = parse_str::<Module>(input); | |
match result { | |
Ok(result) => println!("{result:#?}"), | |
Err(error) => { | |
let span = error.span(); | |
println!("{:?}:{:?} {error:?}", span.start(), span.end()); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment