diff --git a/src/dictionary/layered.rs b/src/dictionary/layered.rs index 75e1c4c9..87d4465a 100644 --- a/src/dictionary/layered.rs +++ b/src/dictionary/layered.rs @@ -140,6 +140,13 @@ impl Dictionary for Layered { None } + fn is_readonly(&self) -> bool { + self.sys_dict + .iter() + .chain(iter::once(&self.user_dict)) + .any(|d| !d.is_readonly()) + } + fn reopen(&mut self) -> Result<(), UpdateDictionaryError> { self.user_dict.reopen() } @@ -347,6 +354,7 @@ mod tests { dict.remove_phrase(&[syl![Bopomofo::C, Bopomofo::E, Bopomofo::TONE4]], "冊") .is_err() ); + assert!(dict.is_readonly()); Ok(()) } } diff --git a/src/dictionary/mod.rs b/src/dictionary/mod.rs index c6486952..41bc07e9 100644 --- a/src/dictionary/mod.rs +++ b/src/dictionary/mod.rs @@ -347,6 +347,8 @@ pub trait Dictionary: Debug { fn about(&self) -> DictionaryInfo; /// Returns the dictionary file path if it's backed by a file. fn path(&self) -> Option<&Path>; + /// Returns whether the dictionary was opened readonly. + fn is_readonly(&self) -> bool; /// Reopens the dictionary if it was changed by a different process /// /// It should not fail if the dictionary is read-only or able to sync across diff --git a/src/dictionary/sqlite.rs b/src/dictionary/sqlite.rs index dcfa8729..392b8fda 100644 --- a/src/dictionary/sqlite.rs +++ b/src/dictionary/sqlite.rs @@ -382,6 +382,10 @@ impl Dictionary for SqliteDictionary { self.path.as_ref().map(|p| p as &Path) } + fn is_readonly(&self) -> bool { + self.readonly + } + fn reopen(&mut self) -> Result<(), UpdateDictionaryError> { Ok(()) } diff --git a/src/dictionary/trie.rs b/src/dictionary/trie.rs index f0ea822a..dda87488 100644 --- a/src/dictionary/trie.rs +++ b/src/dictionary/trie.rs @@ -419,6 +419,10 @@ impl Dictionary for Trie { fn path(&self) -> Option<&Path> { self.path.as_ref().map(|p| p as &Path) } + + fn is_readonly(&self) -> bool { + true + } } fn context_specific( diff --git a/src/dictionary/trie_buf.rs b/src/dictionary/trie_buf.rs index 933e0bae..d32bccc3 100644 --- a/src/dictionary/trie_buf.rs +++ b/src/dictionary/trie_buf.rs @@ -23,6 +23,7 @@ pub struct TrieBuf { graveyard: BTreeSet, join_handle: Option>>, dirty: bool, + readonly: bool, } type PhraseKey = (Cow<'static, [Syllable]>, Cow<'static, str>); @@ -61,6 +62,7 @@ impl TrieBuf { graveyard: BTreeSet::new(), join_handle: None, dirty: false, + readonly: false, }) } @@ -72,6 +74,7 @@ impl TrieBuf { graveyard: BTreeSet::new(), join_handle: None, dirty: false, + readonly: false, } } @@ -257,6 +260,7 @@ impl TrieBuf { graveyard: self.graveyard.clone(), join_handle: None, dirty: false, + readonly: false, }; self.join_handle = Some(thread::spawn(move || { let mut builder = TrieBuilder::new(); @@ -304,6 +308,10 @@ impl Dictionary for TrieBuf { self.trie.as_ref()?.path() } + fn is_readonly(&self) -> bool { + self.readonly + } + fn reopen(&mut self) -> Result<(), UpdateDictionaryError> { self.sync()?; Ok(())