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
//! CMU Sphinx-based Rhyme Tester
//!
//! Small utility to test whether two words rhyme or not. Uses the `cmudict` crate and the CMU
//! Pronunciation dictionary
//!
//! # Example
//!
//! ```
//! extern crate rhyme;
//! use rhyme::Rhyme;
//!
//! # use rhyme::Result;
//! # fn main() -> Result<()> {
//! let rhyme = Rhyme::new()?;
//! if rhyme.rhymes("rust", "trust").unwrap_or(false) {
//!     println!("'rust' and 'trust' rhyme");
//! }
//! #   Ok(())
//! # }
//! ```
extern crate cmudict;

use std::path::Path;

use cmudict::Cmudict;

pub use cmudict::Result;

/// Shortcut for downloading the CMU Dict and testing the two words
///
/// ```
/// # extern crate rhyme;
/// # use rhyme::Result;
/// # fn main() -> Result<()> {
/// if rhyme::rhymes("rust", "trust")?.unwrap_or(false) {
///     println!("'rust' and 'trust' rhyme");
/// }
/// #   Ok(())
/// # }
/// ```
pub fn rhymes(left: &str, right: &str) -> Result<Option<bool>> {
    let r = Rhyme::new()?;
    Ok(r.rhymes(left, right))
}

/// Wrapper around the Cmudict type
pub struct Rhyme(cmudict::Cmudict);

impl Rhyme {
    /// Constructs a new Rhyme struct
    ///
    /// Will download a copy of the CMU Pronunciation dictionary. Use `Rhyme::from_path` if you
    /// want to use an already-saved copy of the dictionary
    pub fn new() -> Result<Rhyme> {
        Ok(Rhyme(Cmudict::download()?))
    }

    /// Constructs a new Rhyme object with the specified CMU Pronunciation dictionary
    pub fn from_path<P: AsRef<Path>>(p: P) -> Result<Rhyme> {
        Ok(Rhyme(Cmudict::new(p)?))
    }

    /// Looks up the two words and returns whether they exist or not
    ///
    /// Returns None if one or both of the words are not in the dictionary
    pub fn rhymes(&self, left: &str, right: &str) -> Option<bool> {
        let left = if let Some(left) = self.0.get(&left) {
            left
        } else {
            return None;
        };

        let right = if let Some(right) = self.0.get(&right) {
            right
        } else {
            return None;
        };

        Some(cmudict::rhymes(&left, &right))
    }
}