use crate::ebook::archive::{Archive, ResourceArchive};
use crate::ebook::errors::ArchiveResult;
use crate::ebook::resource::{Resource, ResourceKey};
use crate::util::uri;
use std::io::Write;
#[cfg(feature = "write")]
use {
crate::ebook::resource::ResourceContent, crate::util::borrow::CowExt, std::borrow::Cow,
std::collections::HashSet,
};
#[derive(Debug)]
pub(super) struct EpubArchive(ResourceArchive);
impl EpubArchive {
pub(super) fn new(base: Box<dyn Archive>) -> Self {
Self(ResourceArchive::new(base))
}
pub(super) fn copy_resource_decoded(
&self,
resource: &Resource,
writer: &mut dyn Write,
) -> ArchiveResult<u64> {
self.0.copy_resource(resource, writer)
}
fn transform_href(href: &str) -> ResourceKey<'_> {
ResourceKey::Value(uri::decode(href))
}
}
#[cfg(feature = "write")]
impl EpubArchive {
pub(super) fn empty() -> Self {
Self(ResourceArchive::empty())
}
pub(super) fn remove(&mut self, href: &str) -> Option<ResourceContent> {
self.0.remove(&Self::transform_href(href))
}
pub(super) fn insert(
&mut self,
href: String,
content: ResourceContent,
) -> Option<ResourceContent> {
self.0.insert(Self::transform_owned_href(href), content)
}
pub(super) fn relocate(&mut self, current: impl Into<String>, new_href: impl Into<String>) {
self.0.relocate(
Self::transform_owned_href(current.into()),
Self::transform_owned_href(new_href.into()),
)
}
pub(super) fn is_overlay_resource(&self, href: &str) -> bool {
self.0.is_overlay_resource(&ResourceKey::from(href))
}
fn transform_owned_href(href: String) -> ResourceKey<'static> {
let decoded = uri::decode(&href).take_owned().unwrap_or(href);
ResourceKey::Value(Cow::Owned(uri::into_absolute(decoded)))
}
}
impl Archive for EpubArchive {
fn copy_resource(&self, resource: &Resource, writer: &mut dyn Write) -> ArchiveResult<u64> {
let transformed = match resource.key() {
ResourceKey::Value(href) => Self::transform_href(href),
ResourceKey::Position(position) => ResourceKey::Position(*position),
};
self.0.copy_resource(&Resource::from(transformed), writer)
}
#[cfg(feature = "write")]
fn resources(&self) -> ArchiveResult<HashSet<Cow<'_, ResourceKey<'_>>>> {
self.0.resources()
}
}