use std::fmt;
use syn::Lit;
use crate::ast::NestedMeta;
use crate::{FromMeta, Result};
use self::Override::*;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Override<T> {
Inherit,
Explicit(T),
}
impl<T> Override<T> {
pub fn as_ref(&self) -> Override<&T> {
match *self {
Inherit => Inherit,
Explicit(ref val) => Explicit(val),
}
}
pub fn as_mut(&mut self) -> Override<&mut T> {
match *self {
Inherit => Inherit,
Explicit(ref mut val) => Explicit(val),
}
}
pub fn is_explicit(&self) -> bool {
match *self {
Inherit => false,
Explicit(_) => true,
}
}
pub fn explicit(self) -> Option<T> {
match self {
Inherit => None,
Explicit(val) => Some(val),
}
}
pub fn unwrap_or(self, optb: T) -> T {
match self {
Inherit => optb,
Explicit(val) => val,
}
}
pub fn unwrap_or_else<F>(self, op: F) -> T
where
F: FnOnce() -> T,
{
match self {
Inherit => op(),
Explicit(val) => val,
}
}
}
impl<T: Default> Override<T> {
pub fn unwrap_or_default(self) -> T {
match self {
Inherit => Default::default(),
Explicit(val) => val,
}
}
}
impl<T> Default for Override<T> {
fn default() -> Self {
Inherit
}
}
impl<T> From<Option<T>> for Override<T> {
fn from(v: Option<T>) -> Self {
match v {
None => Inherit,
Some(val) => Explicit(val),
}
}
}
impl<T: fmt::Display> fmt::Display for Override<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Inherit => write!(f, "Inherit"),
Explicit(ref val) => write!(f, "Explicit `{}`", val),
}
}
}
impl<T: FromMeta> FromMeta for Override<T> {
fn from_meta(item: &syn::Meta) -> Result<Self> {
match item {
syn::Meta::Path(_) => Self::from_word(),
_ => FromMeta::from_meta(item).map(Explicit),
}
}
fn from_word() -> Result<Self> {
Ok(Inherit)
}
fn from_list(items: &[NestedMeta]) -> Result<Self> {
Ok(Explicit(FromMeta::from_list(items)?))
}
fn from_value(lit: &Lit) -> Result<Self> {
Ok(Explicit(FromMeta::from_value(lit)?))
}
fn from_expr(expr: &syn::Expr) -> Result<Self> {
Ok(Explicit(FromMeta::from_expr(expr)?))
}
fn from_char(value: char) -> Result<Self> {
Ok(Explicit(FromMeta::from_char(value)?))
}
fn from_string(value: &str) -> Result<Self> {
Ok(Explicit(FromMeta::from_string(value)?))
}
fn from_bool(value: bool) -> Result<Self> {
Ok(Explicit(FromMeta::from_bool(value)?))
}
}