mod error;
pub use error::{Error, Result};
mod util;
#[doc(hidden)]
pub use paste::paste as __paste;
macro_rules! doc_query_value {
($query_value:item) => {
#[macro_export]
$query_value
};
}
#[cfg(doc)]
doc_query_value! {macro_rules! query_value {
($(mut)? $value:tt $(query:tt)* $(?? $default:expr)?) => {};
($(mut)? $value:tt $(query:tt)* -> $as:ident $(?? $default:expr)?) => {};
($(mut)? $value:tt $(query:tt)* >> ($deser_to:ty) $(?? $default:expr)?) => {};
}}
#[cfg(not(doc))]
doc_query_value! {macro_rules! query_value {
(@trv { $vopt:expr } . $key:ident $($rest:tt)*) => {
$crate::query_value!(@trv { $vopt.and_then(|v| v.get(stringify!($key))) } $($rest)*)
};
(@trv { $vopt:expr } [ $idx:expr ] $($rest:tt)*) => {
$crate::query_value!(@trv { $vopt.and_then(|v| v.get($idx)) } $($rest)*)
};
(@trv { $vopt:expr } -> $dest:ident $($rest:tt)*) => {
$crate::__paste! {
$crate::query_value!(@fin { $vopt.and_then(|v| v.[<as_ $dest>]()) } $($rest)*)
}
};
(@trv { $vopt:expr } >> $dest:ident $($rest:tt)*) => {
$crate::query_value!(@fin { $vopt.and_then(|v| <$dest>::deserialize(v.clone()).ok()) } $($rest)*)
};
(@trv { $vopt:expr } >> ($dest:ty) $($rest:tt)*) => {
$crate::query_value!(@fin { $vopt.and_then(|v| <$dest>::deserialize(v.clone()).ok()) } $($rest)*)
};
(@trv { $vopt:expr } $($rest:tt)*) => {
$crate::query_value!(@fin { $vopt } $($rest)*)
};
(@trv_mut { $vopt:expr } . $key:ident $($rest:tt)*) => {
$crate::query_value!(@trv_mut { $vopt.and_then(|v| v.get_mut(stringify!($key))) } $($rest)*)
};
(@trv_mut { $vopt:expr } [ $idx:expr ] $($rest:tt)*) => {
$crate::query_value!(@trv_mut { $vopt.and_then(|v| v.get_mut($idx)) } $($rest)*)
};
(@trv_mut { $vopt:expr } -> $dest:ident $($rest:tt)*) => {
$crate::__paste! {
$crate::query_value!(@fin { $vopt.and_then(|v| v.[<as_ $dest _mut>]()) } $($rest)*)
}
};
(@trv_mut { $vopt:expr } >> $dest:ident $($rest:tt)*) => {
$crate::query_value!(@fin { $vopt.and_then(|v| <$dest>::deserialize(v.clone()).ok()) } $($rest)*)
};
(@trv_mut { $vopt:expr } >> ($dest:ty) $($rest:tt)*) => {
$crate::query_value!(@fin { $vopt.and_then(|v| <$dest>::deserialize(v.clone()).ok()) } $($rest)*)
};
(@trv_mut { $vopt:expr } $($rest:tt)*) => {
$crate::query_value!(@fin { $vopt } $($rest)*)
};
(@fin { $vopt:expr } ?? default) => {
$vopt.unwrap_or_default()
};
(@fin { $vopt:expr } ?? $default:expr) => {
$vopt.unwrap_or_else(|| $default)
};
(@fin { $vopt:expr }) => {
$vopt
};
(@fin $($_:tt)*) => {
compile_error!("invalid query syntax for query_value!()")
};
(mut $v:tt $($rest:tt)*) => {
$crate::query_value!(@trv_mut { Some(&mut $v) } $($rest)*)
};
($v:tt $($rest:tt)*) => {
$crate::query_value!(@trv { Some(&$v) } $($rest)*)
};
}}
macro_rules! doc_query_value_result {
($query_value_result:item) => {
#[macro_export]
$query_value_result
};
}
#[cfg(doc)]
doc_query_value_result! {macro_rules! query_value_result {
($(mut)? $value:tt $(query:tt)* $(?? $default:expr)?) => {};
($(mut)? $value:tt $(query:tt)* -> $as:ident $(?? $default:expr)?) => {};
($(mut)? $value:tt $(query:tt)* >> ($deser_to:ty) $(?? $default:expr)?) => {};
}}
#[cfg(not(doc))]
doc_query_value_result! {macro_rules! query_value_result {
(@trv [$trace:ident] { $vopt:expr } . $key:ident $($rest:tt)*) => {
$crate::query_value_result!(@trv [$trace] {
$vopt.and_then(|v| {
$trace.push_str(stringify!(.$key));
v.get(stringify!($key)).ok_or_else(|| $crate::Error::ValueNotFoundAtPath($trace.clone()))
})
} $($rest)*)
};
(@trv [$trace:ident] { $vopt:expr } [ $idx:expr ] $($rest:tt)*) => {
$crate::query_value_result!(@trv [$trace] {
$vopt.and_then(|v| {
$trace.push_str(format!("[{}]", stringify!($idx)).as_str());
v.get($idx).ok_or_else(|| $crate::Error::ValueNotFoundAtPath($trace.clone()))
})
} $($rest)*)
};
(@trv [$trace:ident] { $vopt:expr } -> $dest:ident $($rest:tt)*) => {
$crate::__paste! {
$crate::query_value_result!(@fin [$trace] {
$vopt.and_then(|v| {
let conv_name = format!("as_{}", stringify!($dest));
v.[<as_ $dest>]() .ok_or_else(|| $crate::Error::AsCastFailed(conv_name))
})
} $($rest)*)
}
};
(@trv [$trace:ident] { $vopt:expr } >> $dest:ident $($rest:tt)*) => {
$crate::query_value_result!(@fin [$trace] {
$vopt.and_then(|v| {
<$dest>::deserialize(v.clone()).map_err(|e| $crate::Error::DeserializationFailed(Box::new(e)))
})
} $($rest)*)
};
(@trv [$trace:ident] { $vopt:expr } >> ($dest:ty) $($rest:tt)*) => {
$crate::query_value_result!(@fin [$trace] {
$vopt.and_then(|v| {
<$dest>::deserialize(v.clone()).map_err(|e| $crate::Error::DeserializationFailed(Box::new(e)))
})
} $($rest)*)
};
(@trv [$trace:ident] { $vopt:expr } $($rest:tt)*) => {
$crate::query_value_result!(@fin [$trace] { $vopt } $($rest)*)
};
(@trv_mut [$trace:ident] { $vopt:expr } . $key:ident $($rest:tt)*) => {
$crate::query_value_result!(@trv_mut [$trace] {
$vopt.and_then(|v| {
$trace.push_str(stringify!(.$key));
v.get_mut(stringify!($key)).ok_or_else(|| $crate::Error::ValueNotFoundAtPath($trace.clone()))
})
} $($rest)*)
};
(@trv_mut [$trace:ident] { $vopt:expr } [ $idx:expr ] $($rest:tt)*) => {
$crate::query_value_result!(@trv_mut [$trace] {
$vopt.and_then(|v| {
$trace.push_str(format!("[{}]", stringify!($idx)).as_str());
v.get_mut($idx).ok_or_else(|| $crate::Error::ValueNotFoundAtPath($trace.clone()))
})
} $($rest)*)
};
(@trv_mut [$trace:ident] { $vopt:expr } -> $dest:ident $($rest:tt)*) => {
$crate::__paste! {
$crate::query_value_result!(@fin [$trace] {
$vopt.and_then(|v| {
let conv_name = format!("as_{}_mut", stringify!($dest));
v.[<as_ $dest _mut>]().ok_or_else(|| $crate::Error::AsCastFailed(conv_name))
})
} $($rest)*)
}
};
(@trv_mut [$trace:ident] { $vopt:expr } >> $dest:ident $($rest:tt)*) => {
$crate::query_value_result!(@fin [$trace] {
$vopt.and_then(|v| {
<$dest>::deserialize(v.clone()).map_err(|e| $crate::Error::DeserializationFailed(Box::new(e)))
})
} $($rest)*)
};
(@trv_mut [$trace:ident] { $vopt:expr } >> ($dest:ty) $($rest:tt)*) => {
$crate::query_value_result!(@fin [$trace] {
$vopt.and_then(|v| {
<$dest>::deserialize(v.clone()).map_err(|e| $crate::Error::DeserializationFailed(Box::new(e)))
})
} $($rest)*)
};
(@trv_mut [$trace:ident] { $vopt:expr } $($rest:tt)*) => {
$crate::query_value_result!(@fin [$trace] { $vopt } $($rest)*)
};
(@fin [$trace:ident] { $vopt:expr } ?? default) => {
{
use $crate::Error;
let mut $trace = String::new();
$vopt.unwrap_or_default()
}
};
(@fin [$trace:ident] { $vopt:expr } ?? $default:expr) => {
{
use $crate::Error;
let mut $trace = String::new();
$vopt.unwrap_or_else(|_| $default)
}
};
(@fin [$trace:ident] { $vopt:expr }) => {
{
use $crate::Error;
let mut $trace = String::new();
$vopt
}
};
(@fin $($_:tt)*) => {
compile_error!("invalid query syntax for query_value_result!()")
};
(mut $v:tt $($rest:tt)*) => {
$crate::query_value_result!(@trv_mut [trace] { Ok::<_, $crate::Error>(&mut $v) } $($rest)*)
};
($v:tt $($rest:tt)*) => {
$crate::query_value_result!(@trv [trace] { Ok::<_, $crate::Error>(&$v) } $($rest)*)
};
}}