Skip to content

Commit

Permalink
Use rustdoc branch with source feature
Browse files Browse the repository at this point in the history
  • Loading branch information
davisp committed Jan 20, 2025
1 parent a5fe7c2 commit 1b61231
Show file tree
Hide file tree
Showing 18 changed files with 5,486 additions and 3,771 deletions.
92 changes: 61 additions & 31 deletions src/bits/complete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,7 @@ use crate::traits::{Input, ToUsize};
/// Generates a parser taking `count` bits
///
/// # Example
/// ```rust
/// # use nom::bits::complete::take;
/// # use nom::IResult;
/// # use nom::error::{Error, ErrorKind};
/// // Input is a tuple of (input: I, bit_offset: usize)
/// fn parser(input: (&[u8], usize), count: usize)-> IResult<(&[u8], usize), u8> {
/// take(count)(input)
/// }
///
/// // Consumes 0 bits, returns 0
/// assert_eq!(parser(([0b00010010].as_ref(), 0), 0), Ok((([0b00010010].as_ref(), 0), 0)));
///
/// // Consumes 4 bits, returns their values and increase offset to 4
/// assert_eq!(parser(([0b00010010].as_ref(), 0), 4), Ok((([0b00010010].as_ref(), 4), 0b00000001)));
///
/// // Consumes 4 bits, offset is 4, returns their values and increase offset to 0 of next byte
/// assert_eq!(parser(([0b00010010].as_ref(), 4), 4), Ok((([].as_ref(), 0), 0b00000010)));
///
/// // Tries to consume 12 bits but only 8 are available
/// assert_eq!(parser(([0b00010010].as_ref(), 0), 12), Err(nom::Err::Error(Error{input: ([0b00010010].as_ref(), 0), code: ErrorKind::Eof })));
/// ```rust,{source="doctests::example_1"},ignore
/// ```
pub fn take<I, O, C, E: ParseError<(I, usize)>>(
count: C,
Expand Down Expand Up @@ -106,17 +87,7 @@ where
/// Parses one specific bit as a bool.
///
/// # Example
/// ```rust
/// # use nom::bits::complete::bool;
/// # use nom::IResult;
/// # use nom::error::{Error, ErrorKind};
///
/// fn parse(input: (&[u8], usize)) -> IResult<(&[u8], usize), bool> {
/// bool(input)
/// }
///
/// assert_eq!(parse(([0b10000000].as_ref(), 0)), Ok((([0b10000000].as_ref(), 1), true)));
/// assert_eq!(parse(([0b10000000].as_ref(), 1)), Ok((([0b10000000].as_ref(), 2), false)));
/// ```rust,{source="doctests::example_2"},ignore
/// ```
pub fn bool<I, E: ParseError<(I, usize)>>(input: (I, usize)) -> IResult<(I, usize), bool, E>
where
Expand Down Expand Up @@ -193,3 +164,62 @@ mod test {
);
}
}

#[cfg(any(doc, test))]
mod doctests {
use crate as nom;
use nom::bits::complete::{bool, take};
use nom::error::{Error, ErrorKind};
use nom::IResult;

#[test]
fn example() {
// Input is a tuple of (input: I, bit_offset: usize)
fn parser(input: (&[u8], usize), count: usize) -> IResult<(&[u8], usize), u8> {
take(count)(input)
}

// Consumes 0 bits, returns 0
assert_eq!(
parser(([0b00010010].as_ref(), 0), 0),
Ok((([0b00010010].as_ref(), 0), 0))
);

// Consumes 4 bits, returns their values and increase offset to 4
assert_eq!(
parser(([0b00010010].as_ref(), 0), 4),
Ok((([0b00010010].as_ref(), 4), 0b00000001))
);

// Consumes 4 bits, offset is 4, returns their values and increase offset to 0 of next byte
assert_eq!(
parser(([0b00010010].as_ref(), 4), 4),
Ok((([].as_ref(), 0), 0b00000010))
);

// Tries to consume 12 bits but only 8 are available
assert_eq!(
parser(([0b00010010].as_ref(), 0), 12),
Err(nom::Err::Error(Error {
input: ([0b00010010].as_ref(), 0),
code: ErrorKind::Eof
}))
);
}

#[test]
fn example_2() {
fn parse(input: (&[u8], usize)) -> IResult<(&[u8], usize), bool> {
bool(input)
}

assert_eq!(
parse(([0b10000000].as_ref(), 0)),
Ok((([0b10000000].as_ref(), 1), true))
);
assert_eq!(
parse(([0b10000000].as_ref(), 1)),
Ok((([0b10000000].as_ref(), 2), false))
);
}
}
87 changes: 50 additions & 37 deletions src/bits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,7 @@ use crate::Input;
/// away.
///
/// # Example
/// ```
/// use nom::bits::{bits, streaming::take};
/// use nom::error::Error;
/// use nom::IResult;
///
/// fn parse(input: &[u8]) -> IResult<&[u8], (u8, u8)> {
/// bits::<_, _, Error<(&[u8], usize)>, _, _>((take(4usize), take(8usize)))(input)
/// }
///
/// let input = &[0x12, 0x34, 0xff, 0xff];
///
/// let output = parse(input).expect("We take 1.5 bytes and the input is longer than 2 bytes");
///
/// // The first byte is consumed, the second byte is partially consumed and dropped.
/// let remaining = output.0;
/// assert_eq!(remaining, [0xff, 0xff]);
///
/// let parsed = output.1;
/// assert_eq!(parsed.0, 0x01);
/// assert_eq!(parsed.1, 0x23);
/// ```rust,{source="doctests::example_1"},ignore
/// ```
pub fn bits<I, O, E1, E2, P>(mut parser: P) -> impl FnMut(I) -> IResult<I, O, E2>
where
Expand Down Expand Up @@ -63,23 +44,7 @@ where
/// A partial byte remaining in the input will be ignored and the given parser will start parsing
/// at the next full byte.
///
/// ```
/// use nom::bits::{bits, bytes, streaming::take};
/// use nom::combinator::rest;
/// use nom::error::Error;
/// use nom::IResult;
///
/// fn parse(input: &[u8]) -> IResult<&[u8], (u8, u8, &[u8])> {
/// bits::<_, _, Error<(&[u8], usize)>, _, _>((
/// take(4usize),
/// take(8usize),
/// bytes::<_, _, Error<&[u8]>, _, _>(rest)
/// ))(input)
/// }
///
/// let input = &[0x12, 0x34, 0xff, 0xff];
///
/// assert_eq!(parse( input ), Ok(( &[][..], (0x01, 0x23, &[0xff, 0xff][..]) )));
/// ```rust,{source="doctests::example_2"},ignore
/// ```
pub fn bytes<I, O, E1, E2, P>(mut parser: P) -> impl FnMut((I, usize)) -> IResult<(I, usize), O, E2>
where
Expand Down Expand Up @@ -172,3 +137,51 @@ mod test {
assert_eq!("Parsing requires 2 bytes/chars", error.to_string());
}
}

#[cfg(any(doc, test))]
mod doctests {
use crate as nom;

#[test]
fn example_1() {
use nom::bits::{bits, streaming::take};
use nom::error::Error;
use nom::IResult;

fn parse(input: &[u8]) -> IResult<&[u8], (u8, u8)> {
bits::<_, _, Error<(&[u8], usize)>, _, _>((take(4usize), take(8usize)))(input)
}

let input = &[0x12, 0x34, 0xff, 0xff];

let output = parse(input).expect("We take 1.5 bytes and the input is longer than 2 bytes");

// The first byte is consumed, the second byte is partially consumed and dropped.
let remaining = output.0;
assert_eq!(remaining, [0xff, 0xff]);

let parsed = output.1;
assert_eq!(parsed.0, 0x01);
assert_eq!(parsed.1, 0x23);
}

#[test]
fn example_2() {
use nom::bits::{bits, bytes, streaming::take};
use nom::combinator::rest;
use nom::error::Error;
use nom::IResult;

fn parse(input: &[u8]) -> IResult<&[u8], (u8, u8, &[u8])> {
bits::<_, _, Error<(&[u8], usize)>, _, _>((
take(4usize),
take(8usize),
bytes::<_, _, Error<&[u8]>, _, _>(rest),
))(input)
}

let input = &[0x12, 0x34, 0xff, 0xff];

assert_eq!(parse(input), Ok((&[][..], (0x01, 0x23, &[0xff, 0xff][..]))));
}
}
35 changes: 24 additions & 11 deletions src/bits/streaming.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,7 @@ where
/// Parses one specific bit as a bool.
///
/// # Example
/// ```rust
/// # use nom::bits::complete::bool;
/// # use nom::IResult;
/// # use nom::error::{Error, ErrorKind};
///
/// fn parse(input: (&[u8], usize)) -> IResult<(&[u8], usize), bool> {
/// bool(input)
/// }
///
/// assert_eq!(parse(([0b10000000].as_ref(), 0)), Ok((([0b10000000].as_ref(), 1), true)));
/// assert_eq!(parse(([0b10000000].as_ref(), 1)), Ok((([0b10000000].as_ref(), 2), false)));
/// ```rust,{source="doctests::example_1"},ignore
/// ```
pub fn bool<I, E: ParseError<(I, usize)>>(input: (I, usize)) -> IResult<(I, usize), bool, E>
where
Expand Down Expand Up @@ -168,3 +158,26 @@ mod test {
assert_eq!(result, Err(crate::Err::Incomplete(Needed::new(1))));
}
}

#[cfg(any(doc, test))]
mod doctests {
use crate as nom;
use nom::bits::complete::bool;
use nom::IResult;

#[test]
fn example_1() {
fn parse(input: (&[u8], usize)) -> IResult<(&[u8], usize), bool> {
bool(input)
}

assert_eq!(
parse(([0b10000000].as_ref(), 0)),
Ok((([0b10000000].as_ref(), 1), true))
);
assert_eq!(
parse(([0b10000000].as_ref(), 1)),
Ok((([0b10000000].as_ref(), 2), false))
);
}
}
Loading

0 comments on commit 1b61231

Please sign in to comment.