Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

take_while_m_n don't correctly work with custom types #1686

Open
Dangerise opened this issue Aug 16, 2023 · 0 comments
Open

take_while_m_n don't correctly work with custom types #1686

Dangerise opened this issue Aug 16, 2023 · 0 comments

Comments

@Dangerise
Copy link

I implemented the traits that nom requires for Tokens what wraps a slice reference ,
Usually , the functions of nom return like (rest_of_the_input , result)
In the code blow , I expected the return values of wrap a to be empty and b got something , like the return values of wrap2, but things didn't happened like that .

The output

I expected `a` to be empty and `b` has element Variant .
[src\main.rs:27] a = Tokens {
    tok: [
        Variant,
    ],
}
[src\main.rs:27] b = Tokens {
    tok: [],
}

The type &str works well
[src\main.rs:30] a = ""
[src\main.rs:30] b = "1"
#[derive(Debug, Clone, Copy)]
pub enum Token {
    Variant,
}

#[derive(Debug)]
pub struct Tokens<'a> {
    tok: &'a [Token],
}

use nom::bytes::complete::take_while_m_n;

fn wrap(tokens: Tokens) -> IResult<Tokens, Tokens> {
    take_while_m_n(1, 1, |_| true)(tokens)
}

fn wrap2(s: &str) -> IResult<&str, &str> {
    take_while_m_n(1, 1, |_| true)(s)
}

fn main() {
    let slice = &[Token::Variant];
    let tokens = Tokens {
        tok: slice as &[Token],
    };
    let (a, b) = wrap(tokens).unwrap();
    dbg!(a, b);

    let (a, b) = wrap2("1").unwrap();
    dbg!(a, b);
}

impl<'a> From<&'a [Token]> for Tokens<'a> {
    fn from(tok: &'a [Token]) -> Self {
        Self { tok }
    }
}
impl<'a> From<&'a Vec<Token>> for Tokens<'a> {
    fn from(value: &'a Vec<Token>) -> Self {
        Self {
            tok: value.as_slice(),
        }
    }
}

impl<'a> std::ops::Deref for Tokens<'a> {
    type Target = &'a [Token];
    #[inline]
    fn deref(&self) -> &Self::Target {
        &self.tok
    }
}

impl<'a> std::ops::DerefMut for Tokens<'a> {
    #[inline]
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.tok
    }
}

use nom::*;

impl InputLength for Token {
    fn input_len(&self) -> usize {
        1
    }
}

impl<'a> InputTake for Tokens<'a> {
    #[inline]
    fn take(&self, count: usize) -> Self {
        Self {
            tok: &self.tok[..count],
        }
    }
    #[inline]
    fn take_split(&self, count: usize) -> (Self, Self) {
        let (prefix, suffix) = self.tok.split_at(count);
        dbg!(prefix, suffix);
        (Self { tok: prefix }, Self { tok: suffix })
    }
}

impl<'a> InputLength for Tokens<'a> {
    fn input_len(&self) -> usize {
        self.tok.len()
    }
}

use std::ops::{Range, RangeFrom, RangeFull, RangeTo};
impl<'a> Slice<Range<usize>> for Tokens<'a> {
    #[inline]
    fn slice(&self, range: Range<usize>) -> Self {
        Tokens {
            tok: self.tok.slice(range.clone()),
        }
    }
}

impl<'a> Slice<RangeTo<usize>> for Tokens<'a> {
    #[inline]
    fn slice(&self, range: RangeTo<usize>) -> Self {
        self.slice(0..range.end)
    }
}

impl<'a> Slice<RangeFrom<usize>> for Tokens<'a> {
    #[inline]
    fn slice(&self, range: RangeFrom<usize>) -> Self {
        self.slice(range.start..self.len());
        panic!()
    }
}

impl<'a> Slice<RangeFull> for Tokens<'a> {
    #[inline]
    fn slice(&self, _: RangeFull) -> Self {
        Tokens { tok: self.tok }
    }
}

use std::iter::Enumerate;
// use std::slice::Iter;
impl<'a> InputIter for Tokens<'a> {
    type Item = &'a Token;
    type Iter = Enumerate<::std::slice::Iter<'a, Token>>;
    type IterElem = ::std::slice::Iter<'a, Token>;

    #[inline]
    fn iter_indices(&self) -> Enumerate<::std::slice::Iter<'a, Token>> {
        self.tok.iter().enumerate()
    }
    #[inline]
    fn iter_elements(&self) -> ::std::slice::Iter<'a, Token> {
        self.tok.iter()
    }
    #[inline]
    fn position<P>(&self, predicate: P) -> Option<usize>
    where
        P: Fn(Self::Item) -> bool,
    {
        self.tok.iter().position(predicate)
    }
    #[inline]
    fn slice_index(&self, count: usize) -> Result<usize, Needed> {
        if self.tok.len() >= count {
            Ok(count)
        } else {
            Err(Needed::Unknown)
        }
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant