pyphen_rs/pyphen/
builder.rs

1// This file is part of pyphen-rs
2//
3// Copyright 2008 - Wilbert Berendsen <info@wilbertberendsen.nl>
4// Copyright 2012-2013 - Guillaume Ayoub <guillaume.ayoub@kozea.fr>
5// Copyright 2019 - Naresh Ganduri <gandurinaresh@gmail.com>
6//
7// This library is free software.  It is released under the
8// GPL 2.0+/LGPL 2.1+/MPL 1.1 tri-license.  See COPYING.GPL, COPYING.LGPL and
9// COPYING.MPL for more details.
10//
11// This library is distributed in the hope that it will be useful, but WITHOUT
12// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13// FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
14// details.
15
16use std::ops::Deref;
17use std::rc::Rc;
18
19use super::{HyphDict, Pyphen};
20use crate::{language_fallback, HD_CACHE, LANGUAGES};
21
22/// Builder struct to create a hyphenation instance
23pub struct Builder<T> {
24    left: usize,
25    right: usize,
26    cache: bool,
27    filename: T,
28    error: bool,
29}
30
31impl Builder<Rc<String>> {
32    /// Constructs a new Builder for a given language
33    ///
34    /// - *lang* - lang of the included dict to use if no filename is given
35    pub fn lang(lang: &str) -> Self {
36        let mut filename = None;
37        let mut error = false;
38        LANGUAGES.with(|l| {
39            if let Some(fallback) = language_fallback(lang) {
40                if let Some(cpy) = l.borrow().get(&fallback) {
41                    filename = Some(Rc::clone(&cpy));
42                } else {
43                    error = true;
44                }
45            } else {
46                error = true;
47            }
48        });
49        let filename = filename.unwrap_or_default();
50
51        Self {
52            filename,
53            left: 2,
54            right: 2,
55            cache: true,
56            error,
57        }
58    }
59}
60
61impl<T> Builder<T> {
62    /// Constructs a new Builder for a given dictionary file
63    ///
64    /// - *filename* - filename of hyph_*.dic to read
65    pub fn filename(filename: T) -> Self {
66        Self {
67            filename,
68            left: 2,
69            right: 2,
70            cache: true,
71            error: false,
72        }
73    }
74
75    /// Sets the minimum number of characters in the first syllable
76    pub fn left(&mut self, left: usize) -> &mut Self {
77        self.left = left;
78        self
79    }
80
81    /// Sets the minimum number of characters in the last syllable
82    pub fn right(&mut self, right: usize) -> &mut Self {
83        self.right = right;
84        self
85    }
86
87    /// Sets whether to use a cached copy of the hyphenation patterns
88    pub fn cache(&mut self, cache: bool) -> &mut Self {
89        self.cache = cache;
90        self
91    }
92}
93
94impl<T> Builder<T>
95where
96    T: Deref<Target = String>,
97{
98    /// Create an hyphenation instance for given lang or filename.
99    ///
100    /// Returns `Err` if the given lang or filename does not exist.
101    pub fn build(&self) -> Result<Pyphen, ()> {
102        let Self {
103            ref filename,
104            left,
105            right,
106            cache,
107            mut error,
108        } = *self;
109        let filename: &str = &*filename;
110        let mut hd = None;
111
112        HD_CACHE.with(|hc| {
113            if !cache || !hc.borrow().contains_key(filename) {
114                if let Ok(hd) = HyphDict::new(filename) {
115                    hc.borrow_mut().insert(filename.to_string(), Rc::new(hd));
116                } else {
117                    error = true;
118                }
119            }
120
121            if let Some(x) = hc.borrow().get(filename) {
122                hd = Some(Rc::clone(x));
123            } else {
124                error = true;
125            }
126        });
127
128        if error {
129            Err(())
130        } else {
131            let hd = hd.unwrap();
132
133            Ok(Pyphen { hd, left, right })
134        }
135    }
136}