use mf2_catalog::Dir;
use mf2_runtime::Registry;
use crate::LanguageMatching;
#[derive(Clone, Copy)]
pub struct Corpus {
source_locale: &'static str,
manifest_hash: u64,
locales: &'static [(&'static str, Dir)],
registry: &'static Registry,
catalogs: &'static [CatalogFile],
#[cfg_attr(
not(feature = "native"),
allow(dead_code, reason = "read by `mf2::native`")
)]
language_matching: Option<&'static LanguageMatching>,
#[cfg_attr(
not(all(
feature = "host-std",
any(feature = "native", feature = "axum", feature = "ssr")
)),
allow(dead_code, reason = "read where a corpus is formatted from")
)]
host: Option<&'static dyn mf2_runtime::Host>,
#[cfg_attr(
not(feature = "native"),
allow(dead_code, reason = "read by `mf2::native`")
)]
system_zone: Option<fn() -> mf2_runtime::TimeZone>,
}
#[doc(hidden)]
pub trait CorpusHost: mf2_runtime::Host + 'static {
const SYSTEM_ZONE: Option<fn() -> mf2_runtime::TimeZone> = None;
}
#[cfg(feature = "host-std")]
impl CorpusHost for mf2_host_std::StdHost {}
#[cfg(all(feature = "host-std", feature = "datetime"))]
impl CorpusHost for mf2_host_std::ZonesStdHost {
const SYSTEM_ZONE: Option<fn() -> mf2_runtime::TimeZone> = Some(mf2_host_std::system_time_zone);
}
impl core::fmt::Debug for Corpus {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Corpus")
.field("source_locale", &self.source_locale)
.field("manifest_hash", &self.manifest_hash)
.field("locales", &self.locales)
.field("registry", &self.registry)
.field("catalogs", &self.catalogs)
.field("language_matching", &self.language_matching)
.finish_non_exhaustive()
}
}
#[derive(Clone, Copy, Debug)]
pub struct CatalogFile {
tag: &'static str,
file_name: &'static str,
bytes: Option<&'static [u8]>,
server_data: &'static [u8],
}
impl Corpus {
#[doc(hidden)]
#[must_use]
pub const fn new(
source_locale: &'static str,
manifest_hash: u64,
locales: &'static [(&'static str, Dir)],
registry: &'static Registry,
catalogs: &'static [CatalogFile],
) -> Corpus {
Corpus {
source_locale,
manifest_hash,
locales,
registry,
catalogs,
language_matching: None,
host: None,
system_zone: None,
}
}
#[doc(hidden)]
#[must_use]
pub const fn with_language_matching(mut self, matching: &'static LanguageMatching) -> Corpus {
self.language_matching = Some(matching);
self
}
#[doc(hidden)]
#[must_use]
pub const fn with_host<H: CorpusHost>(mut self, host: &'static H) -> Corpus {
self.host = Some(host);
self.system_zone = H::SYSTEM_ZONE;
self
}
#[cfg(feature = "native")]
pub(crate) fn system_zone(&self) -> mf2_runtime::TimeZone {
self.system_zone
.map_or(mf2_runtime::TimeZone::UTC, |read| read())
}
#[cfg(all(
feature = "host-std",
any(feature = "native", feature = "axum", feature = "ssr")
))]
pub(crate) fn host(&self) -> &'static dyn mf2_runtime::Host {
self.host.unwrap_or(&mf2_host_std::HOST)
}
#[cfg(feature = "native")]
pub(crate) fn language_matching(&self) -> &'static LanguageMatching {
self.language_matching.unwrap_or(&LanguageMatching::EMPTY)
}
#[must_use]
pub const fn source_locale(&self) -> &'static str {
self.source_locale
}
#[must_use]
pub const fn manifest_hash(&self) -> u64 {
self.manifest_hash
}
#[must_use]
pub const fn locales(&self) -> &'static [(&'static str, Dir)] {
self.locales
}
#[must_use]
pub const fn registry(&self) -> &'static Registry {
self.registry
}
#[must_use]
pub const fn catalogs(&self) -> &'static [CatalogFile] {
self.catalogs
}
}
impl CatalogFile {
#[doc(hidden)]
#[must_use]
pub const fn new(
tag: &'static str,
file_name: &'static str,
bytes: Option<&'static [u8]>,
) -> CatalogFile {
CatalogFile {
tag,
file_name,
bytes,
server_data: &[],
}
}
#[doc(hidden)]
#[must_use]
pub const fn with_server_data(mut self, table: &'static [u8]) -> CatalogFile {
self.server_data = table;
self
}
#[must_use]
pub const fn tag(&self) -> &'static str {
self.tag
}
#[must_use]
pub const fn file_name(&self) -> &'static str {
self.file_name
}
#[must_use]
pub const fn bytes(&self) -> Option<&'static [u8]> {
self.bytes
}
#[must_use]
pub const fn server_data(&self) -> &'static [u8] {
self.server_data
}
}