swc_config/config_types/
bool_or_data.rsuse serde::{Deserialize, Serialize};
use crate::merge::Merge;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct BoolOrDataConfig<T>(#[serde(default)] Option<BoolOr<T>>);
impl<T> BoolOrDataConfig<T> {
pub fn from_bool(v: bool) -> Self {
Self(Some(BoolOr::Bool(v)))
}
pub fn from_obj(v: T) -> Self {
v.into()
}
pub fn as_ref(&self) -> BoolOrDataConfig<&T> {
match &self.0 {
Some(BoolOr::Data(v)) => BoolOrDataConfig::from_obj(v),
Some(BoolOr::Bool(b)) => BoolOrDataConfig::from_bool(*b),
None => BoolOrDataConfig::default(),
}
}
pub fn or<F>(self, default: F) -> Self
where
F: FnOnce() -> Self,
{
match self.0 {
Some(..) => self,
None => default(),
}
}
pub fn unwrap_as_option<F>(self, default: F) -> Option<T>
where
F: FnOnce(Option<bool>) -> Option<T>,
{
match self.0 {
Some(BoolOr::Data(v)) => Some(v),
Some(BoolOr::Bool(b)) => default(Some(b)),
None => default(None),
}
}
pub fn map<F, N>(self, op: F) -> BoolOrDataConfig<N>
where
F: FnOnce(T) -> N,
{
match self.0 {
Some(BoolOr::Data(v)) => BoolOrDataConfig::from_obj(op(v)),
Some(BoolOr::Bool(b)) => BoolOrDataConfig::from_bool(b),
None => BoolOrDataConfig::default(),
}
}
pub fn is_true(&self) -> bool {
matches!(self.0, Some(BoolOr::Bool(true)))
}
pub fn is_false(&self) -> bool {
matches!(self.0, Some(BoolOr::Bool(false)))
}
pub fn is_obj(&self) -> bool {
matches!(self.0, Some(BoolOr::Data(_)))
}
pub fn into_inner(self) -> Option<BoolOr<T>> {
self.0
}
pub fn inner(&self) -> Option<BoolOr<&T>> {
match &self.0 {
Some(BoolOr::Data(v)) => Some(BoolOr::Data(v)),
Some(BoolOr::Bool(b)) => Some(BoolOr::Bool(*b)),
None => None,
}
}
}
impl<T> From<T> for BoolOrDataConfig<T> {
fn from(v: T) -> Self {
Self(Some(BoolOr::Data(v)))
}
}
impl<T> Default for BoolOrDataConfig<T> {
fn default() -> Self {
Self(Default::default())
}
}
impl<T> Merge for BoolOrDataConfig<T> {
#[inline]
fn merge(&mut self, other: Self) {
self.0.merge(other.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
#[serde(untagged)]
pub enum BoolOr<T> {
Bool(bool),
Data(T),
}
impl<'de, T> Deserialize<'de> for BoolOr<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum Deser<T> {
Bool(bool),
Obj(T),
EmptyObject(EmptyStruct),
}
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct EmptyStruct {}
use serde::__private::de;
let content = de::Content::deserialize(deserializer)?;
let deserializer = de::ContentRefDeserializer::<D::Error>::new(&content);
let res = Deser::deserialize(deserializer);
match res {
Ok(v) => Ok(match v {
Deser::Bool(v) => BoolOr::Bool(v),
Deser::Obj(v) => BoolOr::Data(v),
Deser::EmptyObject(_) => BoolOr::Bool(true),
}),
Err(..) => {
let d = de::ContentDeserializer::<D::Error>::new(content);
Ok(BoolOr::Data(T::deserialize(d)?))
}
}
}
}