use std::str::FromStr;
use super::{Source, StdinError};
#[derive(Clone)]
pub struct MaybeStdin<T> {
inner: T,
is_stdin: bool,
}
impl<T> MaybeStdin<T> {
pub fn is_stdin(&self) -> bool {
self.is_stdin
}
}
impl<T> FromStr for MaybeStdin<T>
where
T: FromStr,
<T as FromStr>::Err: std::fmt::Display,
{
type Err = StdinError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let source = Source::from_str(s)?;
let is_stdin = matches!(source, Source::Stdin);
T::from_str(source.get_value()?.trim())
.map_err(|e| StdinError::FromStr(format!("{e}")))
.map(|val| Self {
inner: val,
is_stdin,
})
}
}
impl<T> MaybeStdin<T> {
pub fn into_inner(self) -> T {
self.inner
}
}
impl<T> std::fmt::Display for MaybeStdin<T>
where
T: std::fmt::Display,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.inner.fmt(f)
}
}
impl<T> std::fmt::Debug for MaybeStdin<T>
where
T: std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.inner.fmt(f)
}
}
impl<T> std::ops::Deref for MaybeStdin<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<T> std::ops::DerefMut for MaybeStdin<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}