summaryrefslogtreecommitdiff
path: root/src/zizek_db.rs
blob: 1195822afd3011a11a5ffd464ba9ac9b9d86fe90 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//! Handling of a database of Slavoj Žižek quotes

use std::fs::File;
use std::io::{self, BufRead, BufReader, BufWriter, Write};
use std::path::Path;

use rand::seq::SliceRandom;

/// Struct containing all currently loaded Žižek quotes and the means to
/// manipulate them.
pub struct ZizekDb
{
    quotes: Vec<String>,
}

impl ZizekDb
{
    /// Read quotes from the file with the given name.
    ///
    /// # Return
    /// Database containing the quotes in case the load was successful or an
    /// `io::Error` in case it could not be loaded.
    pub fn from_file<P>(filename: P) -> Result<Self, io::Error>
    where
        P: AsRef<Path>,
    {
        let file = File::open(filename)?;
        let lines = BufReader::new(file).lines();

        let mut quotes: Vec<String> = Vec::new();
        for line in lines {
            let line = line?.trim().to_owned();
            if !line.is_empty() {
                quotes.push(line);
            }
        }

        Ok(Self { quotes })
    }

    /// Write contents of the database to the file.
    /// The file is overwritten by the contents of the database, so be careful
    /// if you want to concatenate the quotes of this database to the ones
    /// of a different one.
    pub fn write_to_file<P>(&self, filename: P) -> Result<(), io::Error>
    where
        P: AsRef<Path>,
    {
        let file = File::create(filename)?;
        let mut writer = BufWriter::new(file);

        for q in &self.quotes {
            write!(writer, "{}\n", q)?;
        }

        writer.flush()
    }

    /// Check if a quote exists in the database
    ///
    /// # Return
    /// `true` if the quote is registered, `false` if not
    pub fn has_quote(&self, quote: &str) -> bool { self.quotes.iter().any(|q| q == quote) }

    /// Get a random piece of philosophic goodness
    pub fn random_quote(&self) -> Option<&String>
    {
        let mut rng = rand::thread_rng();
        self.quotes.choose(&mut rng)
    }

    /// Add a quote to the index
    ///
    /// # Return
    /// `true` in case the quote was successfully added or `false` if it could
    /// not, in case the quote already exists or an empty string was given.
    pub fn add_quote(&mut self, quote: &str) -> bool
    {
        let quote = quote.trim();

        if quote.is_empty() {
            return false;
        }

        if !self.has_quote(quote) {
            self.quotes.push(quote.to_owned());
            true
        }
        else {
            false
        }
    }

    /// Remove a quote from the database
    ///
    /// # Return
    /// `true` if the quote was found and removed, `false` if there was no such
    /// quote
    pub fn remove_quote(&mut self, quote: &str) -> bool
    {
        for (i, q) in &mut self.quotes.iter_mut().enumerate() {
            if q == quote {
                self.quotes.remove(i);
                return true;
            }
        }

        false
    }
}