markov_generator

Struct Chain

Source
pub struct Chain<T> { /* private fields */ }
Expand description

A Markov chain.

This type implements Serialize and Deserialize when the serde feature is enabled (which it is by default).

Implementations§

Source§

impl<T> Chain<T>

Source

pub fn new(depth: usize) -> Self

Creates a new chain.

See Self::depth for an explanation of the depth.

Examples found in repository?
examples/example.rs (line 23)
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
fn main() {
    const DEPTH: usize = 6;
    // Maps each sequence of 6 items to a list of possible next items.
    let mut chain = Chain::new(DEPTH);

    // In this case, corpus.txt contains one paragraph per line.
    let file = File::open("examples/corpus.txt").unwrap();
    let mut reader = BufReader::new(file);
    let mut line = String::new();
    let mut prev_line = String::new();

    while let Ok(1..) = reader.read_line(&mut line) {
        // `Both` means that the generated random output could start with the
        // beginning of `line`, and that the generated output could end after
        // the end of `line`.
        chain.add_all(line.chars(), AddEdges::Both);

        // Starting index of last `DEPTH` chars in `prev_line`.
        let prev_tail =
            prev_line.char_indices().nth_back(DEPTH - 1).map_or(0, |(i, _)| i);

        // This makes sure there's a chance that the end of the previous line
        // could be followed by the start of the current line when generating
        // random output.
        chain.add_all(
            prev_line[prev_tail..].chars().chain(line.chars().take(DEPTH)),
            AddEdges::Neither,
        );

        std::mem::swap(&mut line, &mut prev_line);
        line.clear();
    }

    // Generate and print random Markov data.
    let output: String = chain
        .generate()
        .flat_map(|c| iter::repeat(c).take(1 + (*c == '\n') as usize))
        .collect();
    print!("{}", &output[..output.len() - 1]);
}
Source

pub fn depth(&self) -> usize

Gets the chain’s depth.

A depth of n means the chain maps sequences of n items of type T to a list of possible next items.

Source§

impl<T: Item> Chain<T>

Source

pub fn add_all<I>(&mut self, items: I, edges: AddEdges)
where I: IntoIterator<Item = T>, T: Clone,

Adds all items in an iterator to the chain.

This essentially calls Self::add_next on every overlapping window of self.depth() + 1 elements.

edges controls whether the start or end of items can be used as start or end data for the chain. See the documentation for AddEdges for more information.

Examples found in repository?
examples/example.rs (line 35)
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
fn main() {
    const DEPTH: usize = 6;
    // Maps each sequence of 6 items to a list of possible next items.
    let mut chain = Chain::new(DEPTH);

    // In this case, corpus.txt contains one paragraph per line.
    let file = File::open("examples/corpus.txt").unwrap();
    let mut reader = BufReader::new(file);
    let mut line = String::new();
    let mut prev_line = String::new();

    while let Ok(1..) = reader.read_line(&mut line) {
        // `Both` means that the generated random output could start with the
        // beginning of `line`, and that the generated output could end after
        // the end of `line`.
        chain.add_all(line.chars(), AddEdges::Both);

        // Starting index of last `DEPTH` chars in `prev_line`.
        let prev_tail =
            prev_line.char_indices().nth_back(DEPTH - 1).map_or(0, |(i, _)| i);

        // This makes sure there's a chance that the end of the previous line
        // could be followed by the start of the current line when generating
        // random output.
        chain.add_all(
            prev_line[prev_tail..].chars().chain(line.chars().take(DEPTH)),
            AddEdges::Neither,
        );

        std::mem::swap(&mut line, &mut prev_line);
        line.clear();
    }

    // Generate and print random Markov data.
    let output: String = chain
        .generate()
        .flat_map(|c| iter::repeat(c).take(1 + (*c == '\n') as usize))
        .collect();
    print!("{}", &output[..output.len() - 1]);
}
Source

pub fn add<I: IntoIterator<Item = Option<T>>>(&mut self, items: I)

Adds items to the chain.

The first self.depth() + 1 items are added, increasing the chance that the first self.depth() items will be followed by the remaining item.

If items.into_iter() yields fewer than self.depth() items, this function is a no-op. If it yields exactly self.depth() items, the remaining item is treated as None.

Source

pub fn add_start<I>(&mut self, items: I)
where I: IntoIterator<Item = T>, I::IntoIter: Clone,

Adds items preceded by various amounts of Nones so that Self::get_start has a chance of returning those items.

Specifically, this function calls Self::add with i Nones followed by the items in items for every i from 1 to self.depth() (inclusive). This increases the chance that the first self.depth() items of items will be returned by Self::get_start.

Note that this function does not increase the chance that the first self.depth() items of items will be followed by the self.depth() + 1st item; Self::add_next or Self::add must be called.

If this function’s trait bounds (I::IntoIter: Clone) are a problem, you can use Self::add_all instead if T is Clone:

chain.add_all(items.into_iter().take(chain.depth()), AddEdges::Start);
Source

pub fn add_next<I: IntoIterator<Item = T>>(&mut self, items: I)

Convenience function that wraps each item in Some and calls Self::add.

Note that this function alone does not increase the chance that items will be returned by Self::get_start; Self::add_start (or manually passing None-prefixed sequences to Self::add) must be used.

Source

pub fn generate(&self) -> Generator<'_, T, ThreadRng>

Available on crate feature std only.

Generates random Markov chain data.

Returns an iterator that yields the elements by reference. If you want them by value, simply use Iterator::cloned (as long as T is Clone).

Examples found in repository?
examples/example.rs (line 55)
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
fn main() {
    const DEPTH: usize = 6;
    // Maps each sequence of 6 items to a list of possible next items.
    let mut chain = Chain::new(DEPTH);

    // In this case, corpus.txt contains one paragraph per line.
    let file = File::open("examples/corpus.txt").unwrap();
    let mut reader = BufReader::new(file);
    let mut line = String::new();
    let mut prev_line = String::new();

    while let Ok(1..) = reader.read_line(&mut line) {
        // `Both` means that the generated random output could start with the
        // beginning of `line`, and that the generated output could end after
        // the end of `line`.
        chain.add_all(line.chars(), AddEdges::Both);

        // Starting index of last `DEPTH` chars in `prev_line`.
        let prev_tail =
            prev_line.char_indices().nth_back(DEPTH - 1).map_or(0, |(i, _)| i);

        // This makes sure there's a chance that the end of the previous line
        // could be followed by the start of the current line when generating
        // random output.
        chain.add_all(
            prev_line[prev_tail..].chars().chain(line.chars().take(DEPTH)),
            AddEdges::Neither,
        );

        std::mem::swap(&mut line, &mut prev_line);
        line.clear();
    }

    // Generate and print random Markov data.
    let output: String = chain
        .generate()
        .flat_map(|c| iter::repeat(c).take(1 + (*c == '\n') as usize))
        .collect();
    print!("{}", &output[..output.len() - 1]);
}
Source

pub fn generate_with_rng<R: Rng>(&self, rng: R) -> Generator<'_, T, R>

Like Self::generate, but takes a custom random number generator.

Source

pub fn get<'a, I>(&'a self, items: I) -> Option<&'a T>
where I: IntoIterator<Item = Option<&'a T>>,

Available on crate feature std only.

Gets a random item that has followed items in the added data.

Only the first self.depth() items are considered. A return value of None either means those items were never followed by anything in the data passed to Self::add, or that None sometimes followed those items and that possibility happened to be picked by the random number generator.

Given iter as items.into_iter(), if iter.next() returns None, it is treated as if it returned Some(None).

Source

pub fn get_with_rng<'a, I, R>(&'a self, items: I, rng: R) -> Option<&'a T>
where I: IntoIterator<Item = Option<&'a T>>, R: Rng,

Like Self::get, but takes a custom random number generator.

Source

pub fn get_start(&self) -> impl Iterator<Item = &T>

Available on crate feature std only.

Gets some initial items that have appeared at the start of a sequence (see Self::add_start).

The returned iterator will yield up to self.depth() items.

Source

pub fn get_start_with_rng<R: Rng>(&self, rng: R) -> impl Iterator<Item = &T>

Like Self::get_start, but takes a custom random number generator.

Source

pub fn get_next<'a, I>(&'a self, items: I) -> Option<&'a T>
where I: IntoIterator<Item = &'a T>,

Available on crate feature std only.

Convenience function that wraps each item in Some and calls Self::get.

Source

pub fn get_next_with_rng<'a, I, R>(&'a self, items: I, rng: R) -> Option<&'a T>
where I: IntoIterator<Item = &'a T>, R: Rng,

Like Self::get_next, but takes a custom random number generator.

Trait Implementations§

Source§

impl<'de, T> Deserialize<'de> for Chain<T>
where T: Item + Deserialize<'de>,

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<T> Serialize for Chain<T>
where T: Item + Serialize,

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<T> Freeze for Chain<T>

§

impl<T> RefUnwindSafe for Chain<T>
where T: RefUnwindSafe,

§

impl<T> Send for Chain<T>
where T: Send,

§

impl<T> Sync for Chain<T>
where T: Sync,

§

impl<T> Unpin for Chain<T>
where T: Unpin,

§

impl<T> UnwindSafe for Chain<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,