|
|
@ -1,13 +1,13 @@ |
|
|
|
use std::collections::BTreeMap; |
|
|
|
use std::collections::BTreeMap; |
|
|
|
use std::collections::LinkedList; |
|
|
|
use std::collections::LinkedList; |
|
|
|
use std::fs::File; |
|
|
|
use std::fs::File; |
|
|
|
use std::io::Read; |
|
|
|
use std::io::{Read, Write}; |
|
|
|
|
|
|
|
|
|
|
|
use serde_derive::Deserialize; |
|
|
|
use serde_derive::Deserialize; |
|
|
|
use serde_derive::Serialize; |
|
|
|
use serde_derive::Serialize; |
|
|
|
use toml; |
|
|
|
use toml; |
|
|
|
|
|
|
|
|
|
|
|
type WordStorage = BTreeMap<char, LinkedList<String>>; |
|
|
|
type WordStorage = BTreeMap<String, LinkedList<String>>; |
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Serialize, Deserialize)] |
|
|
|
#[derive(Debug, Serialize, Deserialize)] |
|
|
|
pub struct WordList { |
|
|
|
pub struct WordList { |
|
|
@ -15,8 +15,12 @@ pub struct WordList { |
|
|
|
metals: WordStorage, |
|
|
|
metals: WordStorage, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)] |
|
|
|
pub enum WordListError { |
|
|
|
pub enum WordListError { |
|
|
|
InvalidFormat, |
|
|
|
InvalidFormat, |
|
|
|
|
|
|
|
InvalidWord, |
|
|
|
|
|
|
|
WordAlreadyExists, |
|
|
|
|
|
|
|
SaveFailure, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl std::convert::From<std::io::Error> for WordListError { |
|
|
|
impl std::convert::From<std::io::Error> for WordListError { |
|
|
@ -31,6 +35,12 @@ impl std::convert::From<toml::de::Error> for WordListError { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl std::convert::From<toml::ser::Error> for WordListError { |
|
|
|
|
|
|
|
fn from(_error: toml::ser::Error) -> WordListError { |
|
|
|
|
|
|
|
WordListError::SaveFailure |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl WordList { |
|
|
|
impl WordList { |
|
|
|
/// Create an empty database
|
|
|
|
/// Create an empty database
|
|
|
|
fn empty() -> Self { |
|
|
|
fn empty() -> Self { |
|
|
@ -41,7 +51,7 @@ impl WordList { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Load the database
|
|
|
|
/// Load the database
|
|
|
|
pub fn load() -> Result<Self, WordListError> { |
|
|
|
fn load() -> Result<Self, WordListError> { |
|
|
|
if let Ok(mut fp) = File::open("database.toml") { |
|
|
|
if let Ok(mut fp) = File::open("database.toml") { |
|
|
|
let mut content = String::new(); |
|
|
|
let mut content = String::new(); |
|
|
|
fp.read_to_string(&mut content)?; |
|
|
|
fp.read_to_string(&mut content)?; |
|
|
@ -51,4 +61,37 @@ impl WordList { |
|
|
|
Ok(WordList::empty()) |
|
|
|
Ok(WordList::empty()) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Save the database
|
|
|
|
|
|
|
|
fn save(&self) -> Result<(), WordListError> { |
|
|
|
|
|
|
|
let content = toml::to_string(&self).unwrap(); |
|
|
|
|
|
|
|
let mut fp = File::create("database.toml")?; |
|
|
|
|
|
|
|
fp.write_all(content.as_bytes())?; |
|
|
|
|
|
|
|
Ok(()) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// add an adjective to the word list
|
|
|
|
|
|
|
|
pub fn insert_adjective(adjective: &str) -> Result<(), WordListError> { |
|
|
|
|
|
|
|
let mut repo = Self::load()?; |
|
|
|
|
|
|
|
let initial = adjective |
|
|
|
|
|
|
|
.chars() |
|
|
|
|
|
|
|
.nth(0) |
|
|
|
|
|
|
|
.ok_or(WordListError::InvalidWord)? |
|
|
|
|
|
|
|
.to_string(); |
|
|
|
|
|
|
|
let mut list = if !repo.adjectives.contains_key(&initial) { |
|
|
|
|
|
|
|
let empty_list = LinkedList::new(); |
|
|
|
|
|
|
|
empty_list |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
repo.adjectives.get(&initial).unwrap().to_owned() |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if list.contains(&adjective.to_string()) { |
|
|
|
|
|
|
|
Err(WordListError::WordAlreadyExists) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
list.push_back(adjective.to_string()); |
|
|
|
|
|
|
|
repo.adjectives.insert(initial, list); |
|
|
|
|
|
|
|
repo.save()?; |
|
|
|
|
|
|
|
Ok(()) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|