pub const GLOSS_DISPLAY_SEPARATOR: &str = ": ";
#[macro_export]
macro_rules! gloss_error {
( $type:ident $(,)? ) => {
$crate::gloss_error!($type, "");
};
( $type:ident, $display_prefix:expr $(,)? ) => {
#[doc = concat!(stringify!($type), " gloss error.")]
#[derive(Clone, Debug, Default, Hash)]
pub struct $type(pub ::std::option::Option<::std::string::String>);
impl $type {
pub fn new<ToStringT>(gloss: ToStringT) -> Self
where
ToStringT: ::std::string::ToString,
{
gloss.to_string().into()
}
#[track_caller]
pub fn as_problem<ToStringT>(gloss: ToStringT) -> $crate::Problem
where
ToStringT: ::std::string::ToString,
{
$crate::Problem::from(Self::new(gloss))
}
#[track_caller]
pub fn default_as_problem() -> $crate::Problem {
$crate::Problem::from(Self::default())
}
}
impl ::std::fmt::Display for $type {
fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
match self.0.as_ref().filter(|gloss| !gloss.is_empty()) {
::std::option::Option::Some(gloss) => {
if $display_prefix.is_empty() {
::std::fmt::Display::fmt(gloss, formatter)
} else {
::std::write!(
formatter,
"{}{}{}",
$display_prefix,
$crate::GLOSS_DISPLAY_SEPARATOR,
gloss
)
}
}
::std::option::Option::None => {
if $display_prefix.is_empty() {
::std::fmt::Display::fmt(stringify!($type), formatter)
} else {
::std::fmt::Display::fmt($display_prefix, formatter)
}
}
}
}
}
impl ::std::error::Error for $type {}
impl ::std::cmp::PartialEq for $type {
fn eq(&self, other: &Self) -> bool {
self.0.eq(&other.0)
}
}
impl ::std::cmp::Eq for $type {}
impl ::std::cmp::PartialOrd for $type {
fn partial_cmp(&self, other: &Self) -> ::std::option::Option<::std::cmp::Ordering> {
self.0.partial_cmp(&other.0)
}
}
impl ::std::cmp::Ord for $type {
fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
self.0.cmp(&other.0)
}
}
impl ::std::convert::From<::std::string::String> for $type {
fn from(gloss: ::std::string::String) -> Self {
Self(::std::option::Option::Some(gloss))
}
}
};
}
#[macro_export]
macro_rules! static_gloss_error {
( $type:ident $(,)? ) => {
$crate::static_gloss_error!($type, "");
};
( $type:ident, $display_prefix:expr $(,)? ) => {
#[doc = concat!(stringify!($type), " gloss error.")]
#[derive(Clone, Debug, Default, Hash)]
pub struct $type(pub ::std::option::Option<&'static str>);
impl $type {
pub fn new<IntoStringT>(gloss: IntoStringT) -> Self
where
IntoStringT: ::std::convert::Into<&'static str>,
{
let gloss: &'static str = gloss.into();
gloss.into()
}
#[track_caller]
pub fn as_problem<IntoStringT>(gloss: IntoStringT) -> $crate::Problem
where
IntoStringT: ::std::convert::Into<&'static str>,
{
$crate::Problem::from(Self::new(gloss))
}
#[track_caller]
pub fn default_as_problem() -> $crate::Problem {
$crate::Problem::from(Self::default())
}
}
impl ::std::fmt::Display for $type {
fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
match self.0.as_ref().filter(|gloss| !gloss.is_empty()) {
::std::option::Option::Some(gloss) => {
if $display_prefix.is_empty() {
::std::fmt::Display::fmt(gloss, formatter)
} else {
::std::write!(
formatter,
"{}{}{}",
$display_prefix,
$crate::GLOSS_DISPLAY_SEPARATOR,
gloss
)
}
}
::std::option::Option::None => {
if $display_prefix.is_empty() {
::std::fmt::Display::fmt(stringify!($type), formatter)
} else {
::std::fmt::Display::fmt($display_prefix, formatter)
}
}
}
}
}
impl ::std::error::Error for $type {}
impl ::std::cmp::PartialEq for $type {
fn eq(&self, other: &Self) -> bool {
self.0.eq(&other.0)
}
}
impl ::std::cmp::Eq for $type {}
impl ::std::cmp::PartialOrd for $type {
fn partial_cmp(&self, other: &Self) -> ::std::option::Option<::std::cmp::Ordering> {
self.0.partial_cmp(&other.0)
}
}
impl ::std::cmp::Ord for $type {
fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
self.0.cmp(&other.0)
}
}
impl ::std::convert::From<&'static str> for $type {
fn from(gloss: &'static str) -> Self {
Self(::std::option::Option::Some(gloss))
}
}
};
}
#[allow(unused_imports)]
pub use {gloss_error, static_gloss_error};