78 lines
1.7 KiB
Rust
78 lines
1.7 KiB
Rust
use crate::core::{EString, ParseFragment, ToEString};
|
|
|
|
impl<T> ToEString for Option<T>
|
|
where
|
|
T: ToEString,
|
|
{
|
|
fn to_estring(&self) -> EString {
|
|
match self {
|
|
Some(inner) => inner.to_estring(),
|
|
None => EString::new(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T> ParseFragment for Option<T>
|
|
where
|
|
T: ParseFragment,
|
|
{
|
|
fn parse_frag(es: EString) -> crate::Result<Self> {
|
|
if es.is_empty() {
|
|
Ok(None)
|
|
} else {
|
|
es.parse().map(Some)
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "aggs")]
|
|
impl<T> crate::core::Aggregatable for Option<T>
|
|
where
|
|
T: crate::core::Aggregatable,
|
|
{
|
|
type Item = T::Item;
|
|
|
|
fn items(self) -> Vec<Self::Item> {
|
|
self.map(T::items).unwrap_or_default()
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use crate::structs::Pair;
|
|
|
|
#[test]
|
|
fn should_parse_empty_string_as_none() {
|
|
let estr = EString::new();
|
|
match estr.parse::<Option<i32>>() {
|
|
Ok(res) => assert_eq!(res, None),
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn should_parse_number_as_some() {
|
|
let estr = EString::from("99");
|
|
match estr.parse::<Option<i32>>() {
|
|
Ok(res) => assert_eq!(res, Some(99)),
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn should_parse_pair() {
|
|
let estr = EString::from("1+2");
|
|
match estr.parse::<Option<Pair<i32, '+', i32>>>() {
|
|
Ok(res) => assert_eq!(res, Some(Pair(1, 2))),
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn should_format_option() {
|
|
assert_eq!(None::<i32>.to_estring(), EString::new());
|
|
assert_eq!(Some(99).to_estring(), EString(String::from("99")));
|
|
}
|
|
}
|