<commit_before>use std::fmt;
use hex_slice::AsHex;
use rand::{random, Rng, XorShiftRng};
use std::rc::Rc;
use std::cell::RefCell;

/// Something that can extract information from an `InfoSource`.
pub trait InfoSink {
    /// The output data.
    type Out;
    /// Called by [InfoSource::draw](trait.InfoSource.html#tymethod.draw)
    fn sink<I: InfoSource>(&mut self, i: &mut I) -> Self::Out;
}

/// Something that an act as a source of test data.
pub trait InfoSource {
    /// Take a single byte from the source.
    fn draw_u8(&mut self) -> u8;

    /// Call F with access to the data source.
    fn draw<S: InfoSink>(&mut self, sink: S) -> S::Out
    where
        Self: Sized;
}

/// Generates data from an underlying Rng instance.
#[derive(Debug)]
pub struct RngSource<R> {
    rng: R,
}

/// An adapter that can record the data drawn from an underlying source.
#[derive(Debug)]
pub struct InfoRecorder<I> {
    inner: Rc<RefCell<I>>,
    pub(crate) data: Vec<u8>,
}

impl<'a, I: InfoSource + ?Sized> InfoSource for &'a mut I {
    fn draw_u8(&mut self) -> u8 {
        (**self).draw_u8()
    }
    fn draw<S: InfoSink>(&mut self, mut sink: S) -> S::Out
    where
        Self: Sized,
    {
        sink.sink(self)
    }
}

impl<I> InfoRecorder<I> {
    /// Creates a recording InfoSource.
    pub fn new(inner: I) -> Self {
        InfoRecorder {
            inner: Rc::new(RefCell::new(inner)),
            data: Vec::new(),
        }
    }

    /// Extracts the data recorded.
    pub fn into_pool(self) -> InfoPool {
        InfoPool::of_vec(self.data)
    }
}

impl<I: InfoSource> InfoSource for InfoRecorder<I> {
    fn draw_u8(&mut self) -> u8 {
        let byte = self.inner.borrow_mut().draw_u8();
        self.data.push(byte);
        byte
    }

    fn draw<S: InfoSink>(&mut self, mut sink: S) -> S::Out
    where
        Self: Sized,
    {
        let start = self.data.len();
        debug!("-> InfoRecorder::draw @{}", start);
        let res = sink.sink(self);
        let end = self.data.len();
        debug!("<- InfoRecorder::draw @{}", end);
        debug!("Span: {:?}", (start, end));
        res
    }
}

impl RngSource<XorShiftRng> {
    /// Creates a RngSource with a randomly seeded XorShift generator.
    pub fn new() -> Self {
        let rng = random::<XorShiftRng>();
        RngSource { rng }
    }
}
<commit_msg>Do not need Rc<RefCell<_>> here.<commit_after>use std::fmt;
use hex_slice::AsHex;
use rand::{random, Rng, XorShiftRng};
use std::rc::Rc;
use std::cell::RefCell;

/// Something that can extract information from an `InfoSource`.
pub trait InfoSink {
    /// The output data.
    type Out;
    /// Called by [InfoSource::draw](trait.InfoSource.html#tymethod.draw)
    fn sink<I: InfoSource>(&mut self, i: &mut I) -> Self::Out;
}

/// Something that an act as a source of test data.
pub trait InfoSource {
    /// Take a single byte from the source.
    fn draw_u8(&mut self) -> u8;

    /// Call F with access to the data source.
    fn draw<S: InfoSink>(&mut self, sink: S) -> S::Out
    where
        Self: Sized;
}

/// Generates data from an underlying Rng instance.
#[derive(Debug)]
pub struct RngSource<R> {
    rng: R,
}

/// An adapter that can record the data drawn from an underlying source.
#[derive(Debug)]
pub struct InfoRecorder<I> {
    inner: I,
    pub(crate) data: Vec<u8>,
}

impl<'a, I: InfoSource + ?Sized> InfoSource for &'a mut I {
    fn draw_u8(&mut self) -> u8 {
        (**self).draw_u8()
    }
    fn draw<S: InfoSink>(&mut self, mut sink: S) -> S::Out
    where
        Self: Sized,
    {
        sink.sink(self)
    }
}

impl<I> InfoRecorder<I> {
    /// Creates a recording InfoSource.
    pub fn new(inner: I) -> Self {
        InfoRecorder {
            inner: inner,
            data: Vec::new(),
        }
    }

    /// Extracts the data recorded.
    pub fn into_pool(self) -> InfoPool {
        InfoPool::of_vec(self.data)
    }
}

impl<I: InfoSource> InfoSource for InfoRecorder<I> {
    fn draw_u8(&mut self) -> u8 {
        let byte = self.inner.draw_u8();
        self.data.push(byte);
        byte
    }

    fn draw<S: InfoSink>(&mut self, mut sink: S) -> S::Out
    where
        Self: Sized,
    {
        let start = self.data.len();
        debug!("-> InfoRecorder::draw @{}", start);
        let res = sink.sink(self);
        let end = self.data.len();
        debug!("<- InfoRecorder::draw @{}", end);
        debug!("Span: {:?}", (start, end));
        res
    }
}

impl RngSource<XorShiftRng> {
    /// Creates a RngSource with a randomly seeded XorShift generator.
    pub fn new() -> Self {
        let rng = random::<XorShiftRng>();
        RngSource { rng }
    }
}

{'fraction_non_alphanumeric': 0.15289079229122055, 'fraction_numerical': 0.003854389721627409, 'mean_word_length': 2.362850971922246, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2312966', 'n_tokens_mistral': 1608, 'n_tokens_neox': 1624, 'n_words': 464}