forked from winstonallo/bitstruct
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.rs
More file actions
54 lines (47 loc) · 1.51 KB
/
Copy pathparser.rs
File metadata and controls
54 lines (47 loc) · 1.51 KB
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
use syn::punctuated::Punctuated;
use syn::token::Struct;
use syn::{
Ident, Result, Token, braced,
parse::{Parse, ParseStream},
};
pub struct BitmapInput {
pub name: Ident,
pub fields: Vec<FieldDef>,
}
impl Parse for BitmapInput {
fn parse(input: ParseStream) -> Result<Self> {
input.parse::<Struct>()?;
let name: Ident = input.parse()?;
let content;
braced!(content in input);
let punctuation: Punctuated<FieldDef, Token![,]> = content.parse_terminated(FieldDef::parse, Token![,])?;
let fields = punctuation.into_iter().collect();
Ok(BitmapInput { name, fields })
}
}
pub struct FieldDef {
pub name: Ident,
pub size: u8,
}
impl Parse for FieldDef {
fn parse(input: ParseStream) -> Result<Self> {
let name: Ident = input.parse()?;
let _: Token![:] = input.parse()?;
let ty: Ident = input.parse()?;
let size = parse_bit_width(&ty)?;
Ok(FieldDef { name, size })
}
}
pub fn parse_bit_width(ty: &syn::Ident) -> Result<u8> {
let ty_str = ty.to_string();
if !ty_str.starts_with("u") {
return Err(syn::Error::new_spanned(ty, format!("Invalid type {ty_str}, expected u{{1..128}}")));
}
let size = ty_str[1..]
.parse::<u8>()
.map_err(|e| syn::Error::new_spanned(ty, format!("Could not parse type size: {e}")))?;
if size == 0 || size > 128 {
return Err(syn::Error::new_spanned(ty, format!("Invalid size for {ty_str}, expected u{{1..128}}")));
}
Ok(size)
}