#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ParseMode {
Strict,
Permissive,
}
impl Default for ParseMode {
fn default() -> Self {
ParseMode::Strict
}
}
impl ParseMode {
pub(crate) fn is_permissive(&self) -> bool {
matches!(self, ParseMode::Permissive)
}
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ParseOptions {
pub parse_mode: ParseMode,
}
impl Default for ParseOptions {
fn default() -> Self {
ParseOptions {
parse_mode: ParseMode::Strict,
}
}
}
impl ParseOptions {
pub fn new() -> Self {
Default::default()
}
pub fn permissive() -> Self {
ParseOptions {
parse_mode: ParseMode::Permissive,
}
}
pub fn strict() -> Self {
ParseOptions {
parse_mode: ParseMode::Strict,
}
}
pub fn with_parse_mode(mut self, parse_mode: ParseMode) -> Self {
self.parse_mode = parse_mode;
self
}
}
pub(crate) trait Permissive<T, E> {
fn or_permissive_and_default(
self,
permissive: bool,
context: &str,
) -> core::result::Result<T, E>;
#[allow(unused)]
fn or_permissive_and_value(
self,
permissive: bool,
context: &str,
value: T,
) -> core::result::Result<T, E>;
#[allow(unused)]
fn or_permissive_and_then<F>(
self,
permissive: bool,
context: &str,
f: F,
) -> core::result::Result<T, E>
where
F: FnOnce() -> T;
}
impl<T: Default, E: core::fmt::Display> Permissive<T, E> for core::result::Result<T, E> {
#[allow(unused)]
fn or_permissive_and_default(
self,
permissive: bool,
context: &str,
) -> core::result::Result<T, E> {
self.or_else(|e| {
if permissive {
#[cfg(feature = "log")]
log::warn!("{context}: {e}, continuing with empty/default value");
Ok(T::default())
} else {
Err(e)
}
})
}
#[allow(unused)]
fn or_permissive_and_value(
self,
permissive: bool,
context: &str,
value: T,
) -> core::result::Result<T, E> {
self.or_else(|e| {
if permissive {
#[cfg(feature = "log")]
log::warn!("{context}: {e}, continuing with provided value");
Ok(value)
} else {
Err(e)
}
})
}
#[allow(unused)]
fn or_permissive_and_then<F>(
self,
permissive: bool,
context: &str,
f: F,
) -> core::result::Result<T, E>
where
F: FnOnce() -> T,
{
self.or_else(|e| {
if permissive {
#[cfg(feature = "log")]
log::warn!("{context}: {e}, continuing with computed value");
Ok(f())
} else {
Err(e)
}
})
}
}