use crate::ebook::element::{Attributes, AttributesData, TextDirection};
use crate::epub::archive::EpubArchive;
use crate::epub::metadata::EpubVersion;
use crate::epub::package::{EpubPackage, EpubPackageData, EpubVersionData, Prefix, Prefixes};
use crate::input::IntoOption;
use crate::util::borrow::CowExt;
use crate::util::uri;
impl EpubPackageData {
pub(in crate::epub) fn new(location: String, version: EpubVersion) -> Self {
Self {
location,
version: EpubVersionData::from(version),
unique_identifier: String::new(),
prefixes: Prefixes::EMPTY,
language: None,
text_direction: TextDirection::Auto,
attributes: AttributesData::default(),
}
}
}
pub struct EpubPackageMut<'ebook> {
archive: &'ebook mut EpubArchive,
package: &'ebook mut EpubPackageData,
}
impl<'ebook> EpubPackageMut<'ebook> {
pub(in crate::epub) fn new(
archive: &'ebook mut EpubArchive,
package: &'ebook mut EpubPackageData,
) -> Self {
EpubPackageMut { archive, package }
}
pub fn set_location(&mut self, location: impl Into<String>) -> String {
let location = location.into();
let normalized = uri::normalize(&location).take_owned().unwrap_or(location);
let absolute = uri::into_absolute(normalized);
let previous = std::mem::replace(&mut self.package.location, absolute);
self.archive.relocate(&previous, &self.package.location);
previous
}
pub fn set_version(&mut self, version: impl Into<EpubVersion>) -> EpubVersion {
let version = version.into();
let previous = self.package.version.parsed;
self.package.version = EpubVersionData::from(version);
previous
}
pub fn set_unique_identifier(&mut self, idref: impl Into<String>) -> String {
std::mem::replace(&mut self.package.unique_identifier, idref.into())
}
pub fn set_text_direction(&mut self, direction: TextDirection) -> TextDirection {
std::mem::replace(&mut self.package.text_direction, direction)
}
pub fn set_xml_language(&mut self, code: impl IntoOption<String>) -> Option<String> {
std::mem::replace(&mut self.package.language, code.into_option())
}
pub fn prefixes_mut(&mut self) -> &mut Prefixes {
&mut self.package.prefixes
}
pub fn attributes_mut(&mut self) -> &mut Attributes {
&mut self.package.attributes
}
pub fn as_view(&self) -> EpubPackage<'_> {
EpubPackage::new(self.package)
}
}
impl Prefix {
pub fn new(name: impl Into<String>, uri: impl Into<String>) -> Self {
Self {
name: name.into(),
uri: uri.into(),
}
}
pub fn set_uri(&mut self, uri: impl Into<String>) -> String {
std::mem::replace(&mut self.uri, uri.into())
}
}
impl<N: Into<String>, U: Into<String>> From<(N, U)> for Prefix {
fn from((name, uri): (N, U)) -> Self {
Self::new(name.into(), uri.into())
}
}
impl Prefixes {
pub fn insert(&mut self, prefix: impl Into<Prefix>) -> Option<Prefix> {
self.0.insert(prefix.into())
}
pub fn by_name_mut(&mut self, name: &str) -> Option<&mut Prefix> {
self.0.by_key_mut(name)
}
pub fn iter_mut(&mut self) -> PrefixesMutIter<'_> {
PrefixesMutIter(self.0.0.iter_mut())
}
pub fn remove(&mut self, name: &str) -> Option<Prefix> {
self.0.remove(name)
}
pub fn retain(&mut self, f: impl FnMut(&Prefix) -> bool) {
self.0.retain(f);
}
pub fn extract_if(&mut self, f: impl FnMut(&Prefix) -> bool) -> impl Iterator<Item = Prefix> {
self.0.extract_if(f)
}
pub fn drain(&mut self) -> impl Iterator<Item = Prefix> {
self.0.drain()
}
pub fn clear(&mut self) {
self.0.clear();
}
}
impl Extend<Prefix> for Prefixes {
fn extend<I: IntoIterator<Item = Prefix>>(&mut self, iter: I) {
for prefix in iter {
self.insert(prefix);
}
}
}
impl<'ebook> IntoIterator for &'ebook mut Prefixes {
type Item = &'ebook mut Prefix;
type IntoIter = PrefixesMutIter<'ebook>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
pub struct PrefixesMutIter<'ebook>(std::slice::IterMut<'ebook, Prefix>);
impl<'ebook> Iterator for PrefixesMutIter<'ebook> {
type Item = &'ebook mut Prefix;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}