use std::borrow::{Borrow, ToOwned};
use std::error::Error;
use std::fmt::{Debug, Display, Formatter};
use crate::message::{Message, MessageFlags};
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SingularPluralMismatchError;
impl Display for SingularPluralMismatchError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "singular/plural type mismatch")
}
}
impl Error for SingularPluralMismatchError {}
pub trait MessageView: Debug {
fn is_singular(&self) -> bool;
fn is_plural(&self) -> bool;
fn is_translated(&self) -> bool;
fn is_fuzzy(&self) -> bool;
fn translator_comments(&self) -> &str;
fn extracted_comments(&self) -> &str;
fn source(&self) -> &str;
fn flags(&self) -> &MessageFlags;
fn msgctxt(&self) -> Option<&str>;
fn msgid(&self) -> &str;
fn msgid_plural(&self) -> Result<&str, SingularPluralMismatchError>;
fn msgstr(&self) -> Result<&str, SingularPluralMismatchError>;
fn msgstr_plural(&self) -> Result<&Vec<String>, SingularPluralMismatchError>;
}
pub trait MessageMutView: MessageView {
fn translator_comments_mut(&mut self) -> &mut String;
fn extracted_comments_mut(&mut self) -> &mut String;
fn source_mut(&mut self) -> &mut String;
fn flags_mut(&mut self) -> &mut MessageFlags;
fn set_msgctxt(&mut self, msgctxt: String);
fn set_msgid(&mut self, msgid: String);
fn set_msgid_plural(&mut self, msgid_plural: String)
-> Result<(), SingularPluralMismatchError>;
fn set_msgstr(&mut self, msgstr: String) -> Result<(), SingularPluralMismatchError>;
fn msgstr_mut(&mut self) -> Result<&mut String, SingularPluralMismatchError>;
fn msgstr_plural_mut(&mut self) -> Result<&mut Vec<String>, SingularPluralMismatchError>;
}
pub trait CatalogMessageMutView: MessageMutView {
fn delete(&mut self);
fn detach(&mut self) -> Message;
}
impl MessageView for Message {
fn is_singular(&self) -> bool {
!self.is_plural
}
fn is_plural(&self) -> bool {
self.is_plural
}
fn is_translated(&self) -> bool {
if self.is_plural {
self.msgstr_plural.iter().all(|x| !x.is_empty())
} else {
!self.msgstr.is_empty()
}
}
fn is_fuzzy(&self) -> bool {
self.flags.is_fuzzy()
}
fn translator_comments(&self) -> &str {
&self.translator_comments
}
fn extracted_comments(&self) -> &str {
&self.extracted_comments
}
fn source(&self) -> &str {
&self.source
}
fn flags(&self) -> &MessageFlags {
&self.flags
}
fn msgctxt(&self) -> Option<&str> {
if self.msgctxt.is_empty() {
None
} else {
Some(&self.msgctxt)
}
}
fn msgid(&self) -> &str {
&self.msgid
}
fn msgid_plural(&self) -> Result<&str, SingularPluralMismatchError> {
if self.is_plural {
Ok(&self.msgid_plural)
} else {
Err(SingularPluralMismatchError)
}
}
fn msgstr(&self) -> Result<&str, SingularPluralMismatchError> {
if self.is_plural {
Err(SingularPluralMismatchError)
} else {
Ok(&self.msgstr)
}
}
fn msgstr_plural(&self) -> Result<&Vec<String>, SingularPluralMismatchError> {
if self.is_plural {
Ok(&self.msgstr_plural)
} else {
Err(SingularPluralMismatchError)
}
}
}
impl MessageMutView for Message {
fn translator_comments_mut(&mut self) -> &mut String {
&mut self.translator_comments
}
fn extracted_comments_mut(&mut self) -> &mut String {
&mut self.extracted_comments
}
fn source_mut(&mut self) -> &mut String {
&mut self.source
}
fn flags_mut(&mut self) -> &mut MessageFlags {
&mut self.flags
}
fn set_msgctxt(&mut self, msgctxt: String) {
self.msgctxt = msgctxt
}
fn set_msgid(&mut self, msgid: String) {
self.msgid = msgid
}
fn set_msgid_plural(
&mut self,
msgid_plural: String,
) -> Result<(), SingularPluralMismatchError> {
if self.is_plural() {
self.msgid_plural = msgid_plural;
Ok(())
} else {
Err(SingularPluralMismatchError)
}
}
fn set_msgstr(&mut self, msgstr: String) -> Result<(), SingularPluralMismatchError> {
if self.is_singular() {
self.msgstr = msgstr;
Ok(())
} else {
Err(SingularPluralMismatchError)
}
}
fn msgstr_mut(&mut self) -> Result<&mut String, SingularPluralMismatchError> {
if self.is_singular() {
Ok(&mut self.msgstr)
} else {
Err(SingularPluralMismatchError)
}
}
fn msgstr_plural_mut(&mut self) -> Result<&mut Vec<String>, SingularPluralMismatchError> {
if self.is_plural() {
Ok(&mut self.msgstr_plural)
} else {
Err(SingularPluralMismatchError)
}
}
}
impl<'a> Borrow<dyn MessageView + 'a> for Message {
fn borrow(&self) -> &(dyn MessageView + 'a) {
self
}
}
impl ToOwned for dyn MessageView {
type Owned = Message;
fn to_owned(&self) -> Self::Owned {
if self.is_singular() {
Self::Owned {
translator_comments: self.translator_comments().to_string(),
extracted_comments: self.extracted_comments().to_string(),
source: self.source().to_string(),
flags: self.flags().clone(),
msgctxt: self.msgctxt().unwrap_or("").to_string(),
msgid: self.msgid().to_string(),
msgid_plural: String::default(),
msgstr: self.msgstr().unwrap().to_string(),
msgstr_plural: vec![],
is_plural: false,
}
} else {
Self::Owned {
translator_comments: self.translator_comments().to_string(),
extracted_comments: self.extracted_comments().to_string(),
source: self.source().to_string(),
flags: self.flags().clone(),
msgctxt: self.msgctxt().unwrap_or("").to_string(),
msgid: self.msgid().to_string(),
msgid_plural: self.msgid_plural().unwrap().to_string(),
msgstr: String::default(),
msgstr_plural: self.msgstr_plural().unwrap().to_owned(),
is_plural: true,
}
}
}
}