use crate::catalog::Catalog;
use crate::message::{
CatalogMessageMutView, Message, MessageFlags, MessageKey, MessageMutView, MessageView,
SingularPluralMismatchError,
};
use std::fmt::{self, Debug, Formatter};
pub struct CatalogMessageRef<C> {
catalog: C,
index: usize,
}
impl<C> CatalogMessageRef<C> {
fn begin(catalog: C) -> Self {
Self { catalog, index: 0 }
}
fn at(catalog: C, index: usize) -> Self {
Self { catalog, index }
}
}
pub struct Iter<'a>(CatalogMessageRef<&'a Catalog>);
impl<'a> Iter<'a> {
pub(crate) fn begin(catalog: &'a Catalog) -> Self {
Self(CatalogMessageRef::begin(catalog))
}
}
impl<'a> Iterator for Iter<'a> {
type Item = &'a dyn MessageView;
fn next(&mut self) -> Option<Self::Item> {
while self.0.index < self.0.catalog.messages.len() {
if let Some(m) = self.0.catalog.messages[self.0.index].as_ref() {
self.0.index += 1;
return Some(m);
} else {
self.0.index += 1
}
}
None
}
}
pub struct IterMut<'a>(CatalogMessageRef<&'a mut Catalog>);
impl<'a> IterMut<'a> {
pub(crate) fn begin(catalog: &'a mut Catalog) -> Self {
Self(CatalogMessageRef::begin(catalog))
}
}
impl<'a> Iterator for IterMut<'a> {
type Item = MessageMutProxy<'a>;
fn next(&mut self) -> Option<Self::Item> {
while self.0.index < self.0.catalog.messages.len() {
if self.0.catalog.messages[self.0.index].is_some() {
let current_index = self.0.index;
self.0.index += 1;
return Some(MessageMutProxy::at(
unsafe { &mut *(self.0.catalog as *mut Catalog) },
current_index,
));
} else {
self.0.index += 1;
}
}
None
}
}
pub struct MessageMutProxy<'a>(CatalogMessageRef<&'a mut Catalog>);
impl<'a> MessageMutProxy<'a> {
pub(crate) fn at(catalog: &'a mut Catalog, index: usize) -> Self {
Self(CatalogMessageRef::at(catalog, index))
}
fn message(&self) -> &Message {
self.0.catalog.messages[self.0.index].as_ref().unwrap()
}
fn message_mut(&mut self) -> &mut Message {
self.0.catalog.messages[self.0.index].as_mut().unwrap()
}
}
impl<'a> Debug for MessageMutProxy<'a> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
self.message().fmt(f)
}
}
impl<'a> MessageView for MessageMutProxy<'a> {
fn is_singular(&self) -> bool {
self.message().is_singular()
}
fn is_plural(&self) -> bool {
self.message().is_plural()
}
fn is_translated(&self) -> bool {
self.message().is_translated()
}
fn is_fuzzy(&self) -> bool {
self.message().is_fuzzy()
}
fn translator_comments(&self) -> &str {
self.message().translator_comments()
}
fn extracted_comments(&self) -> &str {
self.message().extracted_comments()
}
fn source(&self) -> &str {
self.message().source()
}
fn flags(&self) -> &MessageFlags {
self.message().flags()
}
fn msgctxt(&self) -> Option<&str> {
self.message().msgctxt()
}
fn msgid(&self) -> &str {
self.message().msgid()
}
fn msgid_plural(&self) -> Result<&str, SingularPluralMismatchError> {
self.message().msgid_plural()
}
fn msgstr(&self) -> Result<&str, SingularPluralMismatchError> {
self.message().msgstr()
}
fn msgstr_plural(&self) -> Result<&Vec<String>, SingularPluralMismatchError> {
self.message().msgstr_plural()
}
}
impl<'a> MessageMutView for MessageMutProxy<'a> {
fn translator_comments_mut(&mut self) -> &mut String {
&mut self.message_mut().translator_comments
}
fn extracted_comments_mut(&mut self) -> &mut String {
&mut self.message_mut().extracted_comments
}
fn source_mut(&mut self) -> &mut String {
&mut self.message_mut().source
}
fn flags_mut(&mut self) -> &mut MessageFlags {
&mut self.message_mut().flags
}
fn set_msgctxt(&mut self, msgctxt: String) {
let original_key = MessageKey::from(self.message());
self.0.catalog.map.remove(&original_key);
self.message_mut().msgctxt = msgctxt;
let new_key = MessageKey::from(self.message());
self.0.catalog.map.insert(new_key, self.0.index);
}
fn set_msgid(&mut self, msgid: String) {
let original_key = MessageKey::from(self.message());
self.0.catalog.map.remove(&original_key);
self.message_mut().msgctxt = msgid;
let new_key = MessageKey::from(self.message());
self.0.catalog.map.insert(new_key, self.0.index);
}
fn set_msgid_plural(
&mut self,
msgid_plural: String,
) -> Result<(), SingularPluralMismatchError> {
if self.message_mut().is_plural() {
self.message_mut().msgid_plural = msgid_plural;
Ok(())
} else {
Err(SingularPluralMismatchError)
}
}
fn set_msgstr(&mut self, msgstr: String) -> Result<(), SingularPluralMismatchError> {
if self.message_mut().is_plural() {
Err(SingularPluralMismatchError)
} else {
self.message_mut().msgstr = msgstr;
Ok(())
}
}
fn msgstr_mut(&mut self) -> Result<&mut String, SingularPluralMismatchError> {
if self.message_mut().is_plural() {
Err(SingularPluralMismatchError)
} else {
Ok(&mut self.message_mut().msgstr)
}
}
fn msgstr_plural_mut(&mut self) -> Result<&mut Vec<String>, SingularPluralMismatchError> {
if self.message_mut().is_plural() {
Ok(&mut self.message_mut().msgstr_plural)
} else {
Err(SingularPluralMismatchError)
}
}
}
impl<'a> CatalogMessageMutView for MessageMutProxy<'a> {
fn delete(&mut self) {
let key = MessageKey::from(self.message());
self.0.catalog.map.remove(&key);
self.0.catalog.messages[self.0.index] = None;
}
fn detach(&mut self) -> Message {
let key = MessageKey::from(self.message());
self.0.catalog.map.remove(&key);
self.0.catalog.messages[self.0.index].take().unwrap()
}
}