Skip to content

Commit

Permalink
Allow nested chain tags
Browse files Browse the repository at this point in the history
  • Loading branch information
Geal committed Mar 19, 2015
1 parent 6817f46 commit 7023b43
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 38 deletions.
74 changes: 51 additions & 23 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,12 +209,6 @@ macro_rules! o_parser(
/// ```
#[macro_export]
macro_rules! chain (
($name:ident<$i:ty,$o:ty>, $($rest:tt)*) => (
#[allow(unused_variables)]
fn $name(i:$i) -> IResult<$i,$o>{
chaining_parser!(i, $($rest)*)
}
);
($i:expr, $($rest:tt)*) => (
chaining_parser!($i, $($rest)*)
);
Expand Down Expand Up @@ -1504,10 +1498,12 @@ mod tests {
fn temp_ret_int1(i:&[u8]) -> IResult<&[u8], u8> { Done(i,1) };
o!(ret_int1<&[u8],u8> x ~ [ temp_ret_int1 ]);
fn ret_int2(i:&[u8]) -> IResult<&[u8], u8> { Done(i,2) };
chain!(f<&[u8],B>,
aa: ret_int1 ~
bb: ret_int2 ,
||{B{a: aa, b: bb}}
named!(f<&[u8],B>,
chain!(
aa: ret_int1 ~
bb: ret_int2 ,
||{B{a: aa, b: bb}}
)
);

let r = f(b"abcde");
Expand All @@ -1518,14 +1514,17 @@ mod tests {
fn chain2() {
fn ret_int1(i:&[u8]) -> IResult<&[u8], u8> { Done(i,1) };
fn ret_int2(i:&[u8]) -> IResult<&[u8], u8> { Done(i,2) };
chain!(f<&[u8],B>,
tag!("abcd") ~
tag!("abcd")? ~
aa: ret_int1 ~
tag!("efgh") ~
bb: ret_int2 ~
tag!("efgh") ,
||{B{a: aa, b: bb}});
named!(f<&[u8],B>,
chain!(
tag!("abcd") ~
tag!("abcd")? ~
aa: ret_int1 ~
tag!("efgh") ~
bb: ret_int2 ~
tag!("efgh") ,
||{B{a: aa, b: bb}}
)
);

let r = f(b"abcdabcdefghefghX");
assert_eq!(r, Done(b"X", B{a: 1, b: 2}));
Expand All @@ -1534,6 +1533,32 @@ mod tests {
assert_eq!(r2, Done(b"X", B{a: 1, b: 2}));
}

#[test]
fn nested_chain() {
fn ret_int1(i:&[u8]) -> IResult<&[u8], u8> { Done(i,1) };
fn ret_int2(i:&[u8]) -> IResult<&[u8], u8> { Done(i,2) };
tag!(x "abcd");
named!(f<&[u8],B>,
chain!(
chain!(
tag!("abcd") ~
tag!("abcd")? ,
|| {}
) ~
aa: ret_int1 ~
tag!("efgh") ~
bb: ret_int2 ~
tag!("efgh") ,
||{B{a: aa, b: bb}}
)
);

let r = f(b"abcdabcdefghefghX");
assert_eq!(r, Done(b"X", B{a: 1, b: 2}));

let r2 = f(b"abcdefghefghX");
assert_eq!(r2, Done(b"X", B{a: 1, b: 2}));
}
#[derive(PartialEq,Eq,Debug)]
struct C {
a: u8,
Expand All @@ -1548,11 +1573,14 @@ mod tests {
y(i).map(|_| 2)
};

chain!(f<&[u8],C>,
tag!("abcd") ~
aa: ret_int1 ~
bb: ret_y? ,
||{C{a: aa, b: bb}});
named!(f<&[u8],C>,
chain!(
tag!("abcd") ~
aa: ret_int1 ~
bb: ret_y? ,
||{C{a: aa, b: bb}}
)
);

let r = f(b"abcdefghX");
assert_eq!(r, Done(b"X", C{a: 1, b: Some(2)}));
Expand Down
33 changes: 22 additions & 11 deletions tests/ini.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,33 @@ o!(comment_body <&[u8], &[u8]> semicolon ~ [ not_line_ending ]);
o!(comment <&[u8], ()> comment_body ~ line_ending ~ [ empty_result ]);
opt!(opt_comment <&[u8], &[u8]> comment_body);

chain!(category <&[u8], &str>,
named!(category <&[u8], &str>,
chain!(
tag!("[") ~
name: category_name ~
tag!("]") ~
multispace? ,
||{ name }
)
);

chain!(key_value <&[u8],(&str,&str)>,
key: parameter_parser ~
space? ~
tag!("=") ~
space? ~
val: value_parser ~
space? ~
comment_body? ~
multispace? ,
named!(key_value <&[u8],(&str,&str)>,
chain!(
key: parameter_parser ~
space? ~
tag!("=") ~
space? ~
val: value_parser ~
space? ~
chain!(
tag!(";") ~
not_line_ending ,
||{}
)? ~
//comment_body? ~
multispace? ,
||{(key, val)}
)
);


Expand All @@ -73,10 +82,12 @@ fn keys_and_values(input:&[u8]) -> IResult<&[u8], HashMap<&str, &str> > {
}
}

chain!(category_and_keys<&[u8],(&str,HashMap<&str,&str>)>,
named!(category_and_keys<&[u8],(&str,HashMap<&str,&str>)>,
chain!(
category: category ~
keys: keys_and_values ,
move ||{(category, keys)}
)
);

named!(categories_aggregator<&[u8], Vec<(&str, HashMap<&str,&str>)> >, many0!(category_and_keys));
Expand Down
16 changes: 12 additions & 4 deletions tests/mp4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ pub struct Mvhd64 {
take!(ten_bytes 10);

#[allow(non_snake_case)]
chain!(mvhd32 <&[u8], MvhdBox>,
named!(mvhd32 <&[u8], MvhdBox>,
chain!(
version_flags: be_u32 ~
created_date: be_u32 ~
modified_date: be_u32 ~
Expand Down Expand Up @@ -138,10 +139,12 @@ chain!(mvhd32 <&[u8], MvhdBox>,
track_id: track_id
})
}
)
);

#[allow(non_snake_case)]
chain!(mvhd64 <&[u8], MvhdBox>,
named!(mvhd64 <&[u8], MvhdBox>,
chain!(
version_flags: be_u32 ~
created_date: be_u64 ~
modified_date: be_u64 ~
Expand Down Expand Up @@ -189,6 +192,7 @@ chain!(mvhd64 <&[u8], MvhdBox>,
track_id: track_id
})
}
)
);

#[derive(Debug)]
Expand Down Expand Up @@ -367,16 +371,20 @@ alt!(box_type<&[u8], MP4BoxType>, filetype_box_type | moov_box_type | mdat_box_t
alt!(moov_type<&[u8], MP4BoxType>, moov_mdra_type | moov_dref_type | moov_cmov_type | moov_rmra_type | moov_iods_type |
moov_mvhd_type | moov_clip_type | moov_trak_type | moov_udta_type);

chain!(box_header<&[u8],MP4BoxHeader>,
named!(box_header<&[u8],MP4BoxHeader>,
chain!(
length: be_u32 ~
tag: box_type ,
|| { MP4BoxHeader{ length: length, tag: tag} }
)
);

chain!(moov_header<&[u8],MP4BoxHeader>,
named!(moov_header<&[u8],MP4BoxHeader>,
chain!(
length: be_u32 ~
tag: moov_type ,
|| { MP4BoxHeader{ length: length, tag: tag} }
)
);

impl Consumer for MP4Consumer {
Expand Down

0 comments on commit 7023b43

Please sign in to comment.