parser.rs raw

//! Core parser traits and utilities.
//!
//! This module contains the fundamental [`Parser`] trait that all parsers implement,
//! along with the [`Source`] wrapper for managing input streams with position tracking
//! and backtracking support.
//!
//! The [`Parser`] trait uses a Template Method Pattern where the `parse()` method
//! handles caching and backtracking automatically, while implementations provide
//! custom parsing logic in the `read()` method.
//!
//! The module also provides comprehensive blanket implementations for smart pointers
//! like `Box<T>`, `Arc<T>`, `Rc<T>`, and synchronization primitives, enabling
//! flexible parser composition and thread-safe usage patterns.

use std::cell::RefCell;
use std::hash::{DefaultHasher, Hash, Hasher};
use std::io::{Read, Seek};
use std::rc::{Rc, Weak as RcWeak};
use std::sync::{Arc, Mutex as StdMutex, RwLock as StdRwLock, Weak as ArcWeak};

use std::any::{Any, TypeId};

use parking_lot::{Mutex, RwLock};

use crate::{
    cache::{BasicCache, ParsingCache},
    result::{Error, ParseResult},
};

pub trait Parsable: Read + Seek {}

impl<T> Parsable for T where T: Read + Seek {}

/// Encapsulates a [`std::io::Read`] + [`std::io::Seek`] as a source
/// of bytes to parse from.
///
/// Note that while anything that has the required traits will work,
/// using a [`std::io::BufReader`] or [`std::io::Cursor`] will usually
/// be the most efficient choice. Seek capabilities are used heavily
/// while parsing.
pub struct Source<S> {
    source: S,
    stack: Vec<u64>,
    index: u64,
}

impl<S> Source<S>
where
    S: Parsable,
{
    /// Create a new Source wrapping a Read + Seek.
    pub fn new(mut source: S) -> Source<S> {
        let index = source.stream_position().unwrap_or(0);
        Source {
            source,
            stack: Vec::with_capacity(20),
            index,
        }
    }

    /// Store the current location. Each push should be paired with
    /// either a pop (to backtrack to the pushed location) or a commit
    /// (to assert that the pushed location is no longer needed)
    pub fn push(&mut self) {
        self.stack.push(self.index);
    }

    /// Return to the previously pushed location
    pub fn pop(&mut self) {
        self.index = self.stack.pop().unwrap_or(0);
    }

    /// Discard the previously pushed location
    pub fn commit(&mut self) {
        self.stack.pop();
    }

    /// Retrieve the next byte from the source
    pub fn peek1(&mut self) -> Result<u8, Error> {
        let mut buf = [0; 1];
        self.source.seek(std::io::SeekFrom::Start(self.index))?;
        if let Err(err) = self.source.read_exact(&mut buf) {
            if err.kind() == std::io::ErrorKind::UnexpectedEof {
                return Err(Error::NoMatch);
            }
            return Err(Error::from(err));
        }
        Ok(buf[0])
    }

    /// Retrieve the next `bytes` bytes from the source
    pub fn peek(&mut self, bytes: usize) -> Result<Vec<u8>, Error> {
        let mut buf = vec![0; bytes];
        self.source.seek(std::io::SeekFrom::Start(self.index))?;
        if let Err(err) = self.source.read_exact(&mut buf) {
            if err.kind() == std::io::ErrorKind::UnexpectedEof {
                return Err(Error::NoMatch);
            }
            return Err(Error::from(err));
        }
        Ok(buf)
    }

    /// Move the current position in the source forward by `bytes` bytes.
    pub fn advance(&mut self, bytes: usize) {
        self.index += bytes as u64;
    }

    /// Retrieve the next `bytes` bytes from the source, and move the
    /// current position forward by the same number of bytes.
    pub fn read(&mut self, bytes: usize) -> Result<Vec<u8>, Error> {
        let ret = self.peek(bytes)?;
        self.advance(bytes);
        Ok(ret)
    }
}

pub trait Parser<Ctx = ()>
where
    Self: Any,
{
    type Output: Any + Clone;

    /// This is the function you implement in order to make a type Parsable
    fn read<S>(
        &self,
        source: &mut Source<S>,
        cache: &mut impl ParsingCache,
        context: &mut Ctx,
    ) -> ParseResult<Self::Output>
    where
        S: Parsable;

    /// Identifies the specific parser. For parsers which are not
    /// parameterized, the default TypeId-based implementation is
    /// sufficient. However, if the parser is contructed with
    /// parameters, it may need to have a different id for each
    /// combination of parameters in order to avoid false positives in
    /// the cache. For example, the Literal parser needs to override
    /// this so that parsers for different literals are not conflated
    /// in the cache.
    ///
    /// It's recommended that when overridden, the return value should
    /// be generated with [DefaultHasher], and `TypeId::of<Self>()`
    /// should be the first thing added to the hash, followed by
    /// whatever other information is needed to differentiate
    /// instances of the type.
    fn id(&self) -> u64 {
        let mut hasher = DefaultHasher::new();
        TypeId::of::<Self>().hash(&mut hasher);
        hasher.finish()
    }

    /// This is the function you call to try parsing the type from the
    /// source. It is a wrapper which does necessary book-keeping
    /// around calls to the `read` function.
    fn parse<S>(
        &self,
        source: &mut Source<S>,
        cache: &mut impl ParsingCache,
        context: &mut Ctx,
    ) -> ParseResult<Self::Output>
    where
        S: Parsable,
    {
        let parser_id = self.id();

        let before = source.index;

        if let Some((cached_result, after)) = cache.lookup::<Self::Output>(parser_id, before) {
            source.index = after;
            return Ok(cached_result);
        }

        source.push();

        match self.read(source, cache, context) {
            Ok(val) => {
                source.commit();

                // Store result in cache
                cache.record::<Self::Output>(parser_id, before, val.clone(), source.index);
                Ok(val)
            }
            Err(err) => match err {
                Error::NoMatch => {
                    source.pop();
                    Err(err)
                }
                _ => Err(err),
            },
        }
    }
}

/// Global entry point for parsing a grammar
pub fn parse<R, S>(parser: R, source: &mut Source<S>) -> Result<R::Output, Error>
where
    R: Parser,
    S: Parsable,
{
    let mut cache = BasicCache::new();
    let mut context = ();
    parser.parse(source, &mut cache, &mut context)
}

/// Global entry point for parsing a grammar, if you want to specify a cache
pub fn parse_with_cache<R, S>(
    parser: R,
    source: &mut Source<S>,
    cache: &mut impl ParsingCache,
) -> Result<R::Output, Error>
where
    R: Parser,
    S: Parsable,
{
    let mut context = ();
    parser.parse(source, cache, &mut context)
}

/// Global entry point for parsing a grammar with context
pub fn parse_with_context<R, S, Ctx>(
    parser: R,
    source: &mut Source<S>,
    context: &mut Ctx,
) -> Result<R::Output, Error>
where
    R: Parser<Ctx>,
    S: Parsable,
{
    let mut cache = BasicCache::new();
    parser.parse(source, &mut cache, context)
}

/// Global entry point for parsing a grammar with both cache and context
pub fn parse_with_cache_and_context<R, S, Ctx>(
    parser: R,
    source: &mut Source<S>,
    cache: &mut impl ParsingCache,
    context: &mut Ctx,
) -> Result<R::Output, Error>
where
    R: Parser<Ctx>,
    S: Parsable,
{
    parser.parse(source, cache, context)
}

/// () is a Parser which always matches after consuming zero bytes.
impl<Ctx> Parser<Ctx> for () {
    type Output = ();

    fn read<S>(
        &self,
        _source: &mut Source<S>,
        _cache: &mut impl ParsingCache,
        _context: &mut Ctx,
    ) -> ParseResult<Self::Output>
    where
        S: Parsable,
    {
        Ok(())
    }
}

/// Blanket implementation for `Box<T> where T: Parser`
/// This allows boxed parsers to work correctly with the parsing system
impl<T, Ctx> Parser<Ctx> for Box<T>
where
    T: Parser<Ctx>,
{
    type Output = T::Output;

    fn id(&self) -> u64 {
        self.as_ref().id()
    }

    fn read<S>(
        &self,
        source: &mut Source<S>,
        cache: &mut impl ParsingCache,
        context: &mut Ctx,
    ) -> ParseResult<Self::Output>
    where
        S: Parsable,
    {
        self.as_ref().read(source, cache, context)
    }
}

/// Blanket implementation for `Arc<T> where T: Parser`
/// This allows shared parsers to work correctly with the parsing system
impl<T, Ctx> Parser<Ctx> for Arc<T>
where
    T: Parser<Ctx>,
{
    type Output = T::Output;

    fn id(&self) -> u64 {
        self.as_ref().id()
    }

    fn read<S>(
        &self,
        source: &mut Source<S>,
        cache: &mut impl ParsingCache,
        context: &mut Ctx,
    ) -> ParseResult<Self::Output>
    where
        S: Parsable,
    {
        self.as_ref().read(source, cache, context)
    }
}

/// Blanket implementation for `Rc<T> where T: Parser`
/// This allows reference-counted parsers to work correctly with the parsing system
impl<T, Ctx> Parser<Ctx> for Rc<T>
where
    T: Parser<Ctx>,
{
    type Output = T::Output;

    fn id(&self) -> u64 {
        self.as_ref().id()
    }

    fn read<S>(
        &self,
        source: &mut Source<S>,
        cache: &mut impl ParsingCache,
        context: &mut Ctx,
    ) -> ParseResult<Self::Output>
    where
        S: Parsable,
    {
        self.as_ref().read(source, cache, context)
    }
}

/// Blanket implementation for `Mutex<T> where T: Parser`
/// This allows mutex-protected parsers to work correctly with the parsing system
impl<T, Ctx> Parser<Ctx> for Mutex<T>
where
    T: Parser<Ctx>,
{
    type Output = T::Output;

    fn id(&self) -> u64 {
        self.lock().id()
    }

    fn read<S>(
        &self,
        source: &mut Source<S>,
        cache: &mut impl ParsingCache,
        context: &mut Ctx,
    ) -> ParseResult<Self::Output>
    where
        S: Parsable,
    {
        self.lock().read(source, cache, context)
    }
}

/// Blanket implementation for `RwLock<T> where T: Parser`
/// This allows read-write locked parsers to work correctly with the parsing system
impl<T, Ctx> Parser<Ctx> for RwLock<T>
where
    T: Parser<Ctx>,
{
    type Output = T::Output;

    fn id(&self) -> u64 {
        self.read().id()
    }

    fn read<S>(
        &self,
        source: &mut Source<S>,
        cache: &mut impl ParsingCache,
        context: &mut Ctx,
    ) -> ParseResult<Self::Output>
    where
        S: Parsable,
    {
        self.read().read(source, cache, context)
    }
}

/// Blanket implementation for `RefCell<T> where T: Parser`
/// This allows ref-cell protected parsers to work correctly with the parsing system
impl<T, Ctx> Parser<Ctx> for RefCell<T>
where
    T: Parser<Ctx>,
{
    type Output = T::Output;

    fn id(&self) -> u64 {
        self.borrow().id()
    }

    fn read<S>(
        &self,
        source: &mut Source<S>,
        cache: &mut impl ParsingCache,
        context: &mut Ctx,
    ) -> ParseResult<Self::Output>
    where
        S: Parsable,
    {
        self.borrow().read(source, cache, context)
    }
}

/// Blanket implementation for `std::sync::Mutex<T> where T: Parser`
/// This allows standard library mutex-protected parsers to work correctly with the parsing system
/// Panics if the mutex is poisoned
impl<T, Ctx> Parser<Ctx> for StdMutex<T>
where
    T: Parser<Ctx>,
{
    type Output = T::Output;

    fn id(&self) -> u64 {
        self.lock().expect("Mutex poisoned").id()
    }

    fn read<S>(
        &self,
        source: &mut Source<S>,
        cache: &mut impl ParsingCache,
        context: &mut Ctx,
    ) -> ParseResult<Self::Output>
    where
        S: Parsable,
    {
        self.lock()
            .expect("Mutex poisoned")
            .read(source, cache, context)
    }
}

/// Blanket implementation for `std::sync::RwLock<T> where T: Parser`
/// This allows standard library read-write locked parsers to work correctly with the parsing system
/// Panics if the RwLock is poisoned
impl<T, Ctx> Parser<Ctx> for StdRwLock<T>
where
    T: Parser<Ctx>,
{
    type Output = T::Output;

    fn id(&self) -> u64 {
        self.read().expect("RwLock poisoned").id()
    }

    fn read<S>(
        &self,
        source: &mut Source<S>,
        cache: &mut impl ParsingCache,
        context: &mut Ctx,
    ) -> ParseResult<Self::Output>
    where
        S: Parsable,
    {
        self.read()
            .expect("RwLock poisoned")
            .read(source, cache, context)
    }
}

/// Blanket implementation for `ArcWeak<T> where T: Parser`
/// This allows weak references to shared parsers
impl<T, Ctx> Parser<Ctx> for ArcWeak<T>
where
    T: Parser<Ctx>,
{
    type Output = T::Output;

    fn id(&self) -> u64 {
        // For weak references, we need to upgrade to get the id
        // If the upgrade fails, we'll generate a default id based on the type
        if let Some(strong) = self.upgrade() {
            strong.as_ref().id()
        } else {
            // If the reference is dead, generate a consistent id based on the type
            let mut hasher = DefaultHasher::new();
            TypeId::of::<ArcWeak<T>>().hash(&mut hasher);
            hasher.finish()
        }
    }

    fn read<S>(
        &self,
        source: &mut Source<S>,
        cache: &mut impl ParsingCache,
        context: &mut Ctx,
    ) -> ParseResult<Self::Output>
    where
        S: Parsable,
    {
        if let Some(strong) = self.upgrade() {
            strong.as_ref().read(source, cache, context)
        } else {
            Err(Error::NoMatch)
        }
    }
}

/// Blanket implementation for `RcWeak<T> where T: Parser`
/// This allows weak references to reference-counted parsers
impl<T, Ctx> Parser<Ctx> for RcWeak<T>
where
    T: Parser<Ctx>,
{
    type Output = T::Output;

    fn id(&self) -> u64 {
        // For weak references, we need to upgrade to get the id
        // If the upgrade fails, we'll generate a default id based on the type
        if let Some(strong) = self.upgrade() {
            strong.as_ref().id()
        } else {
            // If the reference is dead, generate a consistent id based on the type
            let mut hasher = DefaultHasher::new();
            TypeId::of::<RcWeak<T>>().hash(&mut hasher);
            hasher.finish()
        }
    }

    fn read<S>(
        &self,
        source: &mut Source<S>,
        cache: &mut impl ParsingCache,
        context: &mut Ctx,
    ) -> ParseResult<Self::Output>
    where
        S: Parsable,
    {
        if let Some(strong) = self.upgrade() {
            strong.as_ref().read(source, cache, context)
        } else {
            Err(Error::NoMatch)
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::cache::{BasicCache, NoCache};
    use std::io::Cursor;

    #[test]
    fn test_source_creation() {
        let data = b"hello world";
        let cursor = Cursor::new(data);
        let source = Source::new(cursor);

        assert_eq!(source.index, 0);
        assert!(source.stack.is_empty());
    }

    #[test]
    fn test_source_peek1() {
        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let byte = source.peek1().unwrap();
        assert_eq!(byte, b'h');

        // Position should not change after peek
        assert_eq!(source.index, 0);

        // Peek again should give same result
        let byte2 = source.peek1().unwrap();
        assert_eq!(byte2, b'h');
    }

    #[test]
    fn test_source_peek1_empty() {
        let data = b"";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let result = source.peek1();
        assert!(matches!(result, Err(Error::NoMatch)));
    }

    #[test]
    fn test_source_peek_multiple() {
        let data = b"hello world";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let bytes = source.peek(5).unwrap();
        assert_eq!(bytes, b"hello");

        // Position should not change after peek
        assert_eq!(source.index, 0);

        // Peek more bytes
        let bytes = source.peek(11).unwrap();
        assert_eq!(bytes, b"hello world");
    }

    #[test]
    fn test_source_peek_beyond_end() {
        let data = b"hi";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let result = source.peek(5);
        assert!(matches!(result, Err(Error::NoMatch)));
    }

    #[test]
    fn test_source_advance() {
        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        source.advance(2);
        assert_eq!(source.index, 2);

        let byte = source.peek1().unwrap();
        assert_eq!(byte, b'l');

        source.advance(3);
        assert_eq!(source.index, 5);

        let result = source.peek1();
        assert!(matches!(result, Err(Error::NoMatch)));
    }

    #[test]
    fn test_source_read() {
        let data = b"hello world";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let bytes = source.read(5).unwrap();
        assert_eq!(bytes, b"hello");
        assert_eq!(source.index, 5);

        let byte = source.peek1().unwrap();
        assert_eq!(byte, b' ');

        let bytes = source.read(6).unwrap();
        assert_eq!(bytes, b" world");
        assert_eq!(source.index, 11);
    }

    #[test]
    fn test_source_read_beyond_end() {
        let data = b"hi";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let result = source.read(5);
        assert!(matches!(result, Err(Error::NoMatch)));
        assert_eq!(source.index, 0); // Position should not change on error
    }

    #[test]
    fn test_source_push_pop() {
        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        source.advance(2);
        assert_eq!(source.index, 2);

        source.push();
        assert_eq!(source.stack.len(), 1);

        source.advance(2);
        assert_eq!(source.index, 4);

        source.pop();
        assert_eq!(source.index, 2);
        assert_eq!(source.stack.len(), 0);
    }

    #[test]
    fn test_source_push_commit() {
        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        source.advance(2);
        source.push();
        source.advance(2);
        assert_eq!(source.index, 4);

        source.commit();
        assert_eq!(source.index, 4); // Position stays the same
        assert_eq!(source.stack.len(), 0);
    }

    #[test]
    fn test_source_nested_push_pop() {
        let data = b"hello world";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        // First level
        source.advance(2);
        source.push();

        // Second level
        source.advance(3);
        source.push();

        // Third level
        source.advance(2);
        assert_eq!(source.index, 7);

        // Pop third level
        source.pop();
        assert_eq!(source.index, 5);

        // Pop second level
        source.pop();
        assert_eq!(source.index, 2);
    }

    #[test]
    fn test_source_empty_stack_pop() {
        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        source.advance(3);
        source.pop(); // Should reset to 0
        assert_eq!(source.index, 0);
    }

    #[test]
    fn test_unit_parser() {
        let data = b"anything";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let unit_parser = ();
        parse(unit_parser, &mut source).unwrap();
        assert_eq!(source.index, 0); // Should not advance
    }

    #[test]
    fn test_unit_parser_empty_input() {
        let data = b"";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let unit_parser = ();
        parse(unit_parser, &mut source).unwrap();
    }

    #[test]
    fn test_parse_global_function() {
        let data = b"test";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let unit_parser = ();
        parse(unit_parser, &mut source).unwrap();
    }

    #[test]
    fn test_parse_with_cache_global_function() {
        let data = b"test";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);
        let mut cache = NoCache;

        let unit_parser = ();
        parse_with_cache(unit_parser, &mut source, &mut cache).unwrap();
    }

    #[test]
    fn test_source_position_management() {
        let data = b"0123456789";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        // Test sequential reads
        for i in 0..10 {
            let byte = source.peek1().unwrap();
            assert_eq!(byte, b'0' + i as u8);
            source.advance(1);
            assert_eq!(source.index, i + 1);
        }

        // Should be at end
        let result = source.peek1();
        assert!(matches!(result, Err(Error::NoMatch)));
    }

    #[test]
    fn test_source_large_advance() {
        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        source.advance(1000);
        assert_eq!(source.index, 1000);

        // Should fail to read
        let result = source.peek1();
        assert!(matches!(result, Err(Error::NoMatch)));
    }

    #[test]
    fn test_source_zero_read() {
        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let bytes = source.read(0).unwrap();
        assert_eq!(bytes, b"");
        assert_eq!(source.index, 0);
    }

    #[test]
    fn test_source_zero_peek() {
        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let bytes = source.peek(0).unwrap();
        assert_eq!(bytes, b"");
        assert_eq!(source.index, 0);
    }

    #[test]
    fn test_id_implementation_literal_parsers() {
        // Test that Literal correctly implements custom id() method
        // Different Literal parsers should have different IDs since they have different parameters
        use crate::literal::Literal;

        let literal1 = Literal::from_str("hello");
        let literal2 = Literal::from_str("world");

        // These should have different IDs because they have different content
        assert_ne!(
            <Literal as crate::parser::Parser<()>>::id(&literal1),
            <Literal as crate::parser::Parser<()>>::id(&literal2),
            "Different Literal instances should have different IDs to avoid cache conflicts"
        );

        // Same content should have same ID
        let literal3 = Literal::from_str("hello");
        assert_eq!(
            <Literal as crate::parser::Parser<()>>::id(&literal1),
            <Literal as crate::parser::Parser<()>>::id(&literal3),
            "Literal instances with same content should have same ID for cache efficiency"
        );
    }

    #[test]
    fn test_id_implementation_unit_parser() {
        // Unit parser () uses default id() implementation
        // Since it has no parameters, using default implementation is correct
        let unit1 = ();
        let unit2 = ();

        // These should have the same ID since they're identical
        assert_eq!(
            <() as crate::parser::Parser<()>>::id(&unit1),
            <() as crate::parser::Parser<()>>::id(&unit2),
            "Unit parsers should have same ID since they're functionally identical"
        );
    }

    #[test]
    fn test_parser_caching_behavior() {
        use crate::literal::Literal;

        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);
        let mut cache = BasicCache::new();

        let literal = Literal::from_str("hello");

        // First parse should work and cache result
        let result1 = parse_with_cache(literal.clone(), &mut source, &mut cache).unwrap();
        assert_eq!(result1, b"hello".as_slice().into());

        // Reset position
        source.index = 0;

        // Second parse should use cached result
        let result2 = parse_with_cache(literal, &mut source, &mut cache).unwrap();
        assert_eq!(result2, b"hello".as_slice().into());
    }

    #[test]
    fn test_arc_parser() {
        use crate::literal::Literal;

        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let literal = Arc::new(Literal::from_str("hello"));

        let result = parse(literal, &mut source).unwrap();
        assert_eq!(result, b"hello".as_slice().into());
    }

    #[test]
    fn test_rc_parser() {
        use crate::literal::Literal;

        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let literal = Rc::new(Literal::from_str("hello"));

        let result = parse(literal, &mut source).unwrap();
        assert_eq!(result, b"hello".as_slice().into());
    }

    #[test]
    fn test_arc_mutex_parser() {
        use crate::literal::Literal;

        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let literal = Arc::new(Mutex::new(Literal::from_str("hello")));

        let result = parse(literal, &mut source).unwrap();
        assert_eq!(result, b"hello".as_slice().into());
    }

    #[test]
    fn test_arc_rwlock_parser() {
        use crate::literal::Literal;

        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let literal = Arc::new(RwLock::new(Literal::from_str("hello")));

        let result = parse(literal, &mut source).unwrap();
        assert_eq!(result, b"hello".as_slice().into());
    }

    #[test]
    fn test_rc_refcell_parser() {
        use crate::literal::Literal;

        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let literal = Rc::new(RefCell::new(Literal::from_str("hello")));

        let result = parse(literal, &mut source).unwrap();
        assert_eq!(result, b"hello".as_slice().into());
    }

    #[test]
    fn test_std_mutex_parser() {
        use crate::literal::Literal;

        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let literal = StdMutex::new(Literal::from_str("hello"));

        let result = parse(literal, &mut source).unwrap();
        assert_eq!(result, b"hello".as_slice().into());
    }

    #[test]
    fn test_std_rwlock_parser() {
        use crate::literal::Literal;

        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let literal = StdRwLock::new(Literal::from_str("hello"));

        let result = parse(literal, &mut source).unwrap();
        assert_eq!(result, b"hello".as_slice().into());
    }

    #[test]
    fn test_arc_std_mutex_parser() {
        use crate::literal::Literal;

        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let literal = Arc::new(StdMutex::new(Literal::from_str("hello")));

        let result = parse(literal, &mut source).unwrap();
        assert_eq!(result, b"hello".as_slice().into());
    }

    #[test]
    fn test_arc_std_rwlock_parser() {
        use crate::literal::Literal;

        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let literal = Arc::new(StdRwLock::new(Literal::from_str("hello")));

        let result = parse(literal, &mut source).unwrap();
        assert_eq!(result, b"hello".as_slice().into());
    }

    #[test]
    fn test_smart_pointer_parser_id_consistency() {
        use crate::literal::Literal;

        let base_literal = Literal::from_str("hello");
        let arc_mutex = Arc::new(Mutex::new(Literal::from_str("hello")));
        let arc_rwlock = Arc::new(RwLock::new(Literal::from_str("hello")));
        let rc_refcell = Rc::new(RefCell::new(Literal::from_str("hello")));

        // All should have the same ID since they wrap the same parser
        assert_eq!(
            <Literal as crate::parser::Parser<()>>::id(&base_literal),
            <Arc<Mutex<Literal>> as crate::parser::Parser<()>>::id(&arc_mutex)
        );
        assert_eq!(
            <Literal as crate::parser::Parser<()>>::id(&base_literal),
            <Arc<RwLock<Literal>> as crate::parser::Parser<()>>::id(&arc_rwlock)
        );
        assert_eq!(
            <Literal as crate::parser::Parser<()>>::id(&base_literal),
            <Rc<RefCell<Literal>> as crate::parser::Parser<()>>::id(&rc_refcell)
        );
    }

    #[test]
    fn test_arc_weak_parser_alive() {
        use crate::literal::Literal;

        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let arc_literal = Arc::new(Literal::from_str("hello"));
        let weak_literal = Arc::downgrade(&arc_literal);

        // ID should match the strong reference
        assert_eq!(
            <Arc<Literal> as crate::parser::Parser<()>>::id(&arc_literal),
            <std::sync::Weak<Literal> as crate::parser::Parser<()>>::id(&weak_literal)
        );

        // Should work while the Arc is alive
        let result = parse(weak_literal, &mut source).unwrap();
        assert_eq!(result, b"hello".as_slice().into());
    }

    #[test]
    fn test_arc_weak_parser_dropped() {
        use crate::literal::Literal;

        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let weak_literal = {
            let arc_literal = Arc::new(Literal::from_str("hello"));
            Arc::downgrade(&arc_literal)
        }; // arc_literal is dropped here

        // Should fail with NoMatch since the Arc was dropped
        let result = parse(weak_literal, &mut source);
        assert!(matches!(result, Err(Error::NoMatch)));
    }

    #[test]
    fn test_rc_weak_parser_alive() {
        use crate::literal::Literal;

        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let rc_literal = Rc::new(Literal::from_str("hello"));
        let weak_literal = Rc::downgrade(&rc_literal);

        // ID should match the strong reference
        assert_eq!(
            <Rc<Literal> as crate::parser::Parser<()>>::id(&rc_literal),
            <std::rc::Weak<Literal> as crate::parser::Parser<()>>::id(&weak_literal)
        );

        // Should work while the Rc is alive
        let result = parse(weak_literal, &mut source).unwrap();
        assert_eq!(result, b"hello".as_slice().into());
    }

    #[test]
    fn test_rc_weak_parser_dropped() {
        use crate::literal::Literal;

        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let weak_literal = {
            let rc_literal = Rc::new(Literal::from_str("hello"));
            Rc::downgrade(&rc_literal)
        }; // rc_literal is dropped here

        // Should fail with NoMatch since the Rc was dropped
        let result = parse(weak_literal, &mut source);
        assert!(matches!(result, Err(Error::NoMatch)));
    }

    #[test]
    fn test_arc_weak_mutex_parser_alive() {
        use crate::literal::Literal;

        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let arc_literal = Arc::new(Mutex::new(Literal::from_str("hello")));
        let weak_literal = Arc::downgrade(&arc_literal);

        // ID should match the strong reference
        assert_eq!(
            <Arc<Mutex<Literal>> as crate::parser::Parser<()>>::id(&arc_literal),
            <std::sync::Weak<Mutex<Literal>> as crate::parser::Parser<()>>::id(&weak_literal)
        );

        // Should work while the Arc is alive
        let result = parse(weak_literal, &mut source).unwrap();
        assert_eq!(result, b"hello".as_slice().into());
    }

    #[test]
    fn test_arc_weak_mutex_parser_dropped() {
        use crate::literal::Literal;

        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let weak_literal = {
            let arc_literal = Arc::new(Mutex::new(Literal::from_str("hello")));
            Arc::downgrade(&arc_literal)
        }; // arc_literal is dropped here

        // Should fail with NoMatch since the Arc was dropped
        let result = parse(weak_literal, &mut source);
        assert!(matches!(result, Err(Error::NoMatch)));
    }

    #[test]
    fn test_arc_weak_rwlock_parser_alive() {
        use crate::literal::Literal;

        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let arc_literal = Arc::new(RwLock::new(Literal::from_str("hello")));
        let weak_literal = Arc::downgrade(&arc_literal);

        // ID should match the strong reference
        assert_eq!(
            <Arc<RwLock<Literal>> as crate::parser::Parser<()>>::id(&arc_literal),
            <std::sync::Weak<RwLock<Literal>> as crate::parser::Parser<()>>::id(&weak_literal)
        );

        // Should work while the Arc is alive
        let result = parse(weak_literal, &mut source).unwrap();
        assert_eq!(result, b"hello".as_slice().into());
    }

    #[test]
    fn test_rc_weak_refcell_parser_alive() {
        use crate::literal::Literal;

        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let rc_literal = Rc::new(RefCell::new(Literal::from_str("hello")));
        let weak_literal = Rc::downgrade(&rc_literal);

        // ID should match the strong reference
        assert_eq!(
            <Rc<RefCell<Literal>> as crate::parser::Parser<()>>::id(&rc_literal),
            <std::rc::Weak<RefCell<Literal>> as crate::parser::Parser<()>>::id(&weak_literal)
        );

        // Should work while the Rc is alive
        let result = parse(weak_literal, &mut source).unwrap();
        assert_eq!(result, b"hello".as_slice().into());
    }

    #[test]
    fn test_rc_weak_refcell_parser_dropped() {
        use crate::literal::Literal;

        let data = b"hello";
        let cursor = Cursor::new(data);
        let mut source = Source::new(cursor);

        let weak_literal = {
            let rc_literal = Rc::new(RefCell::new(Literal::from_str("hello")));
            Rc::downgrade(&rc_literal)
        }; // rc_literal is dropped here

        // Should fail with NoMatch since the Rc was dropped
        let result = parse(weak_literal, &mut source);
        assert!(matches!(result, Err(Error::NoMatch)));
    }
}