remove unused code
This commit is contained in:
parent
efa00a408b
commit
d8575073f1
15 changed files with 115 additions and 172 deletions
|
@ -1,20 +1,20 @@
|
|||
use eww_config::{
|
||||
format_diagnostic::ToDiagnostic,
|
||||
parser::{ast::*, from_ast::FromAst},
|
||||
};
|
||||
// use eww_config::{
|
||||
// format_diagnostic::ToDiagnostic,
|
||||
// parser::{ast::*, from_ast::FromAst},
|
||||
//};
|
||||
|
||||
fn main() {
|
||||
let mut files = codespan_reporting::files::SimpleFiles::new();
|
||||
// let mut files = codespan_reporting::files::SimpleFiles::new();
|
||||
|
||||
let input = r#"
|
||||
(heyho ; :foo { "foo \" } bar " }
|
||||
; :baz {(foo == bar ? 12.2 : 12)}
|
||||
(foo)
|
||||
(defwidget foo [something bla] "foo")
|
||||
(baz))"#;
|
||||
// let input = r#"
|
||||
//(heyho ; :foo { "foo \" } bar " }
|
||||
//; :baz {(foo == bar ? 12.2 : 12)}
|
||||
//(foo)
|
||||
//(defwidget foo [something bla] "foo")
|
||||
//(baz))"#;
|
||||
|
||||
let file_id = files.add("foo.eww", input);
|
||||
let ast = eww_config::parser::parse_string(file_id, input);
|
||||
// let file_id = files.add("foo.eww", input);
|
||||
// let ast = eww_config::parser::parse_string(file_id, input);
|
||||
// match ast.and_then(eww_config::parser::from_ast::Element::<Ast, Ast>::from_ast) {
|
||||
// Ok(ast) => {
|
||||
// println!("{:?}", ast);
|
||||
|
|
|
@ -14,7 +14,6 @@ use crate::{
|
|||
ast_iterator::AstIterator,
|
||||
from_ast::{FromAst, FromAstElementContent},
|
||||
},
|
||||
spanned,
|
||||
value::{AttrName, VarName},
|
||||
};
|
||||
|
||||
|
@ -28,13 +27,10 @@ pub enum TopLevel {
|
|||
impl FromAst for TopLevel {
|
||||
fn from_ast(e: Ast) -> AstResult<Self> {
|
||||
let span = e.span();
|
||||
spanned!(e.span(), {
|
||||
let mut iter = e.try_ast_iter()?;
|
||||
let (sym_span, element_name) = iter.expect_symbol()?;
|
||||
match element_name.as_str() {
|
||||
x if x == WidgetDefinition::get_element_name() => {
|
||||
Self::WidgetDefinition(WidgetDefinition::from_tail(span, iter)?)
|
||||
}
|
||||
Ok(match element_name.as_str() {
|
||||
x if x == WidgetDefinition::get_element_name() => Self::WidgetDefinition(WidgetDefinition::from_tail(span, iter)?),
|
||||
x if x == VarDefinition::get_element_name() => Self::VarDefinition(VarDefinition::from_tail(span, iter)?),
|
||||
x if x == PollScriptVar::get_element_name() => {
|
||||
Self::ScriptVarDefinition(ScriptVarDefinition::Poll(PollScriptVar::from_tail(span, iter)?))
|
||||
|
@ -42,11 +38,8 @@ impl FromAst for TopLevel {
|
|||
x if x == TailScriptVar::get_element_name() => {
|
||||
Self::ScriptVarDefinition(ScriptVarDefinition::Tail(TailScriptVar::from_tail(span, iter)?))
|
||||
}
|
||||
x if x == WindowDefinition::get_element_name() => {
|
||||
Self::WindowDefinition(WindowDefinition::from_tail(span, iter)?)
|
||||
}
|
||||
x => return Err(AstError::UnknownToplevel(Some(sym_span), x.to_string())),
|
||||
}
|
||||
x if x == WindowDefinition::get_element_name() => Self::WindowDefinition(WindowDefinition::from_tail(span, iter)?),
|
||||
x => return Err(AstError::UnknownToplevel(sym_span, x.to_string())),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ use crate::{
|
|||
ast_iterator::AstIterator,
|
||||
from_ast::{FromAst, FromAstElementContent},
|
||||
},
|
||||
spanned,
|
||||
value::{AttrName, VarName},
|
||||
};
|
||||
|
||||
|
@ -50,8 +49,8 @@ impl FromAstElementContent for PollScriptVar {
|
|||
fn from_tail<I: Iterator<Item = Ast>>(span: Span, mut iter: AstIterator<I>) -> AstResult<Self> {
|
||||
let (_, name) = iter.expect_symbol()?;
|
||||
let mut attrs = iter.expect_key_values()?;
|
||||
let interval: String = attrs.primitive_required("interval")?;
|
||||
let interval = crate::util::parse_duration(&interval).map_err(|e| AstError::Other(Some(span), e.into()))?;
|
||||
let interval = attrs.primitive_required::<DynVal, _>("interval")?.as_duration()?;
|
||||
// let interval = interval.as_duration()?;
|
||||
let (_, script) = iter.expect_literal()?;
|
||||
Ok(Self { name: VarName(name), command: VarSource::Shell(script.to_string()), interval })
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ use crate::{
|
|||
ast_iterator::AstIterator,
|
||||
from_ast::FromAst,
|
||||
},
|
||||
spanned,
|
||||
value::{AttrName, VarName},
|
||||
};
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ use crate::{
|
|||
ast_iterator::AstIterator,
|
||||
from_ast::{FromAst, FromAstElementContent},
|
||||
},
|
||||
spanned,
|
||||
value::{AttrName, VarName},
|
||||
};
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ use crate::{
|
|||
ast_iterator::AstIterator,
|
||||
from_ast::{FromAst, FromAstElementContent},
|
||||
},
|
||||
spanned,
|
||||
value::{AttrName, VarName},
|
||||
};
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ use crate::{
|
|||
ast_iterator::AstIterator,
|
||||
from_ast::FromAst,
|
||||
},
|
||||
spanned,
|
||||
value::AttrName,
|
||||
};
|
||||
|
||||
|
@ -27,9 +26,8 @@ pub struct WidgetUse {
|
|||
impl FromAst for WidgetUse {
|
||||
fn from_ast(e: Ast) -> AstResult<Self> {
|
||||
let span = e.span();
|
||||
spanned!(e.span(), {
|
||||
if let Ok(text) = e.as_literal_ref() {
|
||||
Self {
|
||||
Ok(Self {
|
||||
name: "text".to_string(),
|
||||
attrs: Attributes::new(
|
||||
span.into(),
|
||||
|
@ -42,14 +40,13 @@ impl FromAst for WidgetUse {
|
|||
),
|
||||
children: Vec::new(),
|
||||
span,
|
||||
}
|
||||
})
|
||||
} else {
|
||||
let mut iter = e.try_ast_iter()?;
|
||||
let (_, name) = iter.expect_symbol()?;
|
||||
let attrs = iter.expect_key_values()?;
|
||||
let children = iter.map(WidgetUse::from_ast).collect::<AstResult<Vec<_>>>()?;
|
||||
Self { name, attrs, children, span }
|
||||
}
|
||||
})
|
||||
Ok(Self { name, attrs, children, span })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ use crate::{
|
|||
ast_iterator::AstIterator,
|
||||
from_ast::{FromAst, FromAstElementContent},
|
||||
},
|
||||
spanned,
|
||||
value::{AttrName, NumWithUnit, VarName},
|
||||
};
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use simplexpr::{dynval::DynVal, SimplExpr};
|
|||
use crate::{enum_parse, error::{AstError, AstResult}, parser::{
|
||||
ast::{Ast, Span}, ast_iterator::AstIterator,
|
||||
from_ast::{FromAst, FromAstElementContent},
|
||||
}, spanned, value::{AttrName, Coords, VarName}};
|
||||
}, value::{AttrName, Coords, VarName}};
|
||||
|
||||
use super::{widget_use::WidgetUse, window_definition::EnumParseError};
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
|
101
src/error.rs
101
src/error.rs
|
@ -6,6 +6,7 @@ use crate::{
|
|||
},
|
||||
};
|
||||
use codespan_reporting::{diagnostic, files};
|
||||
use simplexpr::dynval;
|
||||
use thiserror::Error;
|
||||
|
||||
pub type AstResult<T> = Result<T, AstError>;
|
||||
|
@ -13,15 +14,18 @@ pub type AstResult<T> = Result<T, AstError>;
|
|||
#[derive(Debug, Error)]
|
||||
pub enum AstError {
|
||||
#[error("Unknown toplevel declaration `{1}`")]
|
||||
UnknownToplevel(Option<Span>, String),
|
||||
UnknownToplevel(Span, String),
|
||||
#[error("Expected another element, but got nothing")]
|
||||
MissingNode(Option<Span>),
|
||||
MissingNode(Span),
|
||||
#[error("Wrong type of expression: Expected {1} but got {2}")]
|
||||
WrongExprType(Option<Span>, AstType, AstType),
|
||||
WrongExprType(Span, AstType, AstType),
|
||||
#[error("Expected to get a value, but got {1}")]
|
||||
NotAValue(Option<Span>, AstType),
|
||||
NotAValue(Span, AstType),
|
||||
#[error("Expected element {1}, but read {2}")]
|
||||
MismatchedElementName(Option<Span>, String, String),
|
||||
MismatchedElementName(Span, String, String),
|
||||
|
||||
#[error(transparent)]
|
||||
ConversionError(#[from] dynval::ConversionError),
|
||||
|
||||
#[error("{1}")]
|
||||
Other(Option<Span>, Box<dyn std::error::Error>),
|
||||
|
@ -29,13 +33,6 @@ pub enum AstError {
|
|||
#[error(transparent)]
|
||||
AttrError(#[from] AttrError),
|
||||
|
||||
//#[error("{msg}: {source}")]
|
||||
// Context {
|
||||
// span: Option<Span>,
|
||||
//#[source]
|
||||
// source: Box<dyn std::error::Error>,
|
||||
// msg: String,
|
||||
//},
|
||||
#[error(transparent)]
|
||||
ValidationError(#[from] ValidationError),
|
||||
|
||||
|
@ -46,14 +43,14 @@ pub enum AstError {
|
|||
impl AstError {
|
||||
pub fn get_span(&self) -> Option<Span> {
|
||||
match self {
|
||||
AstError::UnknownToplevel(span, _) => *span,
|
||||
AstError::MissingNode(span) => *span,
|
||||
AstError::WrongExprType(span, ..) => *span,
|
||||
AstError::NotAValue(span, ..) => *span,
|
||||
AstError::MismatchedElementName(span, ..) => *span,
|
||||
AstError::UnknownToplevel(span, _) => Some(*span),
|
||||
AstError::MissingNode(span) => Some(*span),
|
||||
AstError::WrongExprType(span, ..) => Some(*span),
|
||||
AstError::NotAValue(span, ..) => Some(*span),
|
||||
AstError::MismatchedElementName(span, ..) => Some(*span),
|
||||
AstError::AttrError(err) => Some(err.span()),
|
||||
AstError::Other(span, ..) => *span,
|
||||
// AstError::Context { span, .. } => *span,
|
||||
AstError::ConversionError(err) => err.value.span().map(|x| x.into()),
|
||||
AstError::ValidationError(error) => None, // TODO none here is stupid
|
||||
AstError::ParseError { file_id, source } => file_id.and_then(|id| get_parse_error_span(id, source)),
|
||||
}
|
||||
|
@ -83,55 +80,25 @@ fn get_parse_error_span(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn spanned(span: Span, err: impl Into<AstError>) -> AstError {
|
||||
use AstError::*;
|
||||
match err.into() {
|
||||
UnknownToplevel(None, x) => UnknownToplevel(Some(span), x),
|
||||
MissingNode(None) => MissingNode(Some(span)),
|
||||
WrongExprType(None, x, y) => WrongExprType(Some(span), x, y),
|
||||
UnknownToplevel(None, x) => UnknownToplevel(Some(span), x),
|
||||
MissingNode(None) => MissingNode(Some(span)),
|
||||
NotAValue(None, x) => NotAValue(Some(span), x),
|
||||
MismatchedElementName(None, x, y) => MismatchedElementName(Some(span), x, y),
|
||||
// Context { span: None, source, msg } => Context { span: Some(span), source, msg },
|
||||
Other(None, x) => Other(Some(span), x),
|
||||
x => x,
|
||||
}
|
||||
}
|
||||
|
||||
pub trait OptionAstErrorExt<T> {
|
||||
fn or_missing(self) -> Result<T, AstError>;
|
||||
}
|
||||
impl<T> OptionAstErrorExt<T> for Option<T> {
|
||||
fn or_missing(self) -> Result<T, AstError> {
|
||||
self.ok_or(AstError::MissingNode(None))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AstResultExt<T> {
|
||||
fn at(self, span: Span) -> Result<T, AstError>;
|
||||
}
|
||||
|
||||
pub trait Context<T> {
|
||||
fn context(self, span: Span, msg: String) -> Result<T, AstError>;
|
||||
}
|
||||
|
||||
impl<T, E: Into<AstError>> AstResultExt<T> for Result<T, E> {
|
||||
fn at(self, span: Span) -> Result<T, AstError> {
|
||||
self.map_err(|err| spanned(span, err))
|
||||
}
|
||||
}
|
||||
|
||||
// impl<T, E: std::error::Error + 'static> Context<T> for Result<T, E> {
|
||||
// fn context(self, span: Span, msg: String) -> Result<T, AstError> {
|
||||
// self.map_err(|x| AstError::Context { msg, span: Some(span), source: Box::new(x) })
|
||||
// pub fn spanned(span: Span, err: impl Into<AstError>) -> AstError {
|
||||
// use AstError::*;
|
||||
// match err.into() {
|
||||
// UnknownToplevel(s, x) => UnknownToplevel(Some(s.unwrap_or(span)), x),
|
||||
// MissingNode(s) => MissingNode(Some(s.unwrap_or(span))),
|
||||
// WrongExprType(s, x, y) => WrongExprType(Some(s.unwrap_or(span)), x, y),
|
||||
// UnknownToplevel(s, x) => UnknownToplevel(Some(s.unwrap_or(span)), x),
|
||||
// MissingNode(s) => MissingNode(Some(s.unwrap_or(span))),
|
||||
// NotAValue(s, x) => NotAValue(Some(s.unwrap_or(span)), x),
|
||||
// MismatchedElementName(s, expected, got) => MismatchedElementName(Some(s.unwrap_or(span)), expected, got),
|
||||
// Other(s, x) => Other(Some(s.unwrap_or(span)), x),
|
||||
// x @ ConversionError(_) | x @ AttrError(_) | x @ ValidationError(_) | x @ ParseError { .. } => x,
|
||||
//}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! spanned {
|
||||
($span:expr, $block:expr) => {{
|
||||
let span = $span;
|
||||
let result: Result<_, crate::error::AstError> = try { $block };
|
||||
crate::error::AstResultExt::at(result, span)
|
||||
}};
|
||||
pub trait OptionAstErrorExt<T> {
|
||||
fn or_missing(self, span: Span) -> Result<T, AstError>;
|
||||
}
|
||||
impl<T> OptionAstErrorExt<T> for Option<T> {
|
||||
fn or_missing(self, span: Span) -> Result<T, AstError> {
|
||||
self.ok_or(AstError::MissingNode(span))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ macro_rules! gen_diagnostic {
|
|||
$(, note = $note:expr)? $(,)?
|
||||
) => {
|
||||
Diagnostic::error()
|
||||
$(.with_message($msg))?
|
||||
$(.with_message($msg.to_string()))?
|
||||
$(.with_labels(vec![
|
||||
Label::primary($span.2, $span.0..$span.1)
|
||||
$(.with_message($label))?
|
||||
|
@ -23,7 +23,7 @@ macro_rules! gen_diagnostic {
|
|||
};
|
||||
($msg:expr $(, $span:expr $(,)?)?) => {{
|
||||
Diagnostic::error()
|
||||
.with_message($msg)
|
||||
.with_message($msg.to_string())
|
||||
$(.with_labels(vec![Label::primary($span.2, $span.0..$span.1)]))?
|
||||
}};
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ impl ToDiagnostic for AstError {
|
|||
note = format!("Expected: {}\nGot: {}", expected, actual),
|
||||
},
|
||||
AstError::NotAValue(_, actual) => gen_diagnostic! {
|
||||
msg = format!("Expected value, but got {}", actual),
|
||||
msg = format!("Expected value, but got `{}`", actual),
|
||||
label = span => "Expected some value here",
|
||||
note = format!("Got: {}", actual),
|
||||
},
|
||||
|
@ -73,7 +73,15 @@ impl ToDiagnostic for AstError {
|
|||
parse_error::ParseError::SimplExpr(_, error) => simplexpr_error_to_diagnostic(error, span),
|
||||
parse_error::ParseError::LexicalError(_) => lexical_error_to_diagnostic(span),
|
||||
}),
|
||||
_ => panic!(),
|
||||
AstError::MismatchedElementName(_, expected, got) => gen_diagnostic! {
|
||||
msg = format!("Expected element `{}`, but found `{}`", expected, got),
|
||||
label = span => format!("Expected `{}` here", expected),
|
||||
note = format!("Expected: {}\nGot: {}", expected, got),
|
||||
},
|
||||
AstError::ConversionError(err) => conversion_error_to_diagnostic(err, span),
|
||||
AstError::Other(_, source) => gen_diagnostic!(source, span),
|
||||
AstError::AttrError(source) => gen_diagnostic!(source, span),
|
||||
AstError::ValidationError(_) => todo!(),
|
||||
}
|
||||
} else {
|
||||
Diagnostic::error().with_message(format!("{}", self))
|
||||
|
@ -107,9 +115,9 @@ fn simplexpr_error_to_diagnostic(error: &simplexpr::error::Error, span: Span) ->
|
|||
match error {
|
||||
ParseError { source, .. } => lalrpop_error_to_diagnostic(source, span, move |error| lexical_error_to_diagnostic(span)),
|
||||
ConversionError(error) => conversion_error_to_diagnostic(error, span),
|
||||
Eval(error) => gen_diagnostic!(format!("{}", error), span),
|
||||
Other(error) => gen_diagnostic!(format!("{}", error), span),
|
||||
Spanned(_, error) => gen_diagnostic!(format!("{}", error), span),
|
||||
Eval(error) => gen_diagnostic!(error, span),
|
||||
Other(error) => gen_diagnostic!(error, span),
|
||||
Spanned(_, error) => gen_diagnostic!(error, span),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -92,14 +92,14 @@ macro_rules! as_func {
|
|||
pub fn $name(self) -> Result<$t, AstError> {
|
||||
match self {
|
||||
$p => Ok($value),
|
||||
x => Err(AstError::WrongExprType(Some(x.span()), $exprtype, x.expr_type())),
|
||||
x => Err(AstError::WrongExprType(x.span(), $exprtype, x.expr_type())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn $nameref(&self) -> Result<&$t, AstError> {
|
||||
match self {
|
||||
$p => Ok($value),
|
||||
x => Err(AstError::WrongExprType(Some(x.span()), $exprtype, x.expr_type())),
|
||||
x => Err(AstError::WrongExprType(x.span(), $exprtype, x.expr_type())),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -145,7 +145,7 @@ impl Ast {
|
|||
// Ast::Symbol(_, _) => todo!(),
|
||||
Ast::Literal(span, x) => Ok(SimplExpr::Literal(span.into(), x)),
|
||||
Ast::SimplExpr(span, x) => Ok(x),
|
||||
_ => Err(AstError::WrongExprType(Some(self.span()), AstType::IntoPrimitive, self.expr_type())),
|
||||
_ => Err(AstError::WrongExprType(self.span(), AstType::IntoPrimitive, self.expr_type())),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,19 +23,18 @@ macro_rules! return_or_put_back {
|
|||
($name:ident, $expr_type:expr, $t:ty = $p:pat => $ret:expr) => {
|
||||
pub fn $name(&mut self) -> AstResult<$t> {
|
||||
let expr_type = $expr_type;
|
||||
match self.next() {
|
||||
Some($p) => {
|
||||
match self.expect_any()? {
|
||||
$p => {
|
||||
let (span, value) = $ret;
|
||||
self.remaining_span.1 = span.1;
|
||||
Ok((span, value))
|
||||
}
|
||||
Some(other) => {
|
||||
other => {
|
||||
let span = other.span();
|
||||
let actual_type = other.expr_type();
|
||||
self.iter.put_back(other);
|
||||
Err(AstError::WrongExprType(Some(span), expr_type, actual_type))
|
||||
Err(AstError::WrongExprType(span, expr_type, actual_type))
|
||||
}
|
||||
None => Err(AstError::MissingNode(None)),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -55,7 +54,7 @@ impl<I: Iterator<Item = Ast>> AstIterator<I> {
|
|||
}
|
||||
|
||||
pub fn expect_any<T: FromAst>(&mut self) -> AstResult<T> {
|
||||
self.iter.next().or_missing().and_then(T::from_ast)
|
||||
self.iter.next().or_missing(self.remaining_span.with_length(0)).and_then(T::from_ast)
|
||||
}
|
||||
|
||||
pub fn expect_key_values(&mut self) -> AstResult<Attributes> {
|
||||
|
|
|
@ -2,7 +2,7 @@ use super::{
|
|||
ast::{Ast, AstType, Span},
|
||||
ast_iterator::AstIterator,
|
||||
};
|
||||
use crate::{error::*, parser, spanned, util, value::AttrName};
|
||||
use crate::{error::*, parser, util, value::AttrName};
|
||||
use itertools::Itertools;
|
||||
use simplexpr::{ast::SimplExpr, dynval::DynVal};
|
||||
use std::{
|
||||
|
@ -37,14 +37,12 @@ pub trait FromAstElementContent: Sized {
|
|||
impl<T: FromAstElementContent> FromAst for T {
|
||||
fn from_ast(e: Ast) -> AstResult<Self> {
|
||||
let span = e.span();
|
||||
spanned!(e.span(), {
|
||||
let mut iter = e.try_ast_iter()?;
|
||||
let (_, element_name) = iter.expect_symbol()?;
|
||||
if Self::get_element_name() != element_name {
|
||||
return Err(AstError::MismatchedElementName(Some(span), Self::get_element_name().to_string(), element_name));
|
||||
return Err(AstError::MismatchedElementName(span, Self::get_element_name().to_string(), element_name));
|
||||
}
|
||||
Self::from_tail(span, iter)?
|
||||
})
|
||||
Self::from_tail(span, iter)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,7 +52,7 @@ impl FromAst for SimplExpr {
|
|||
Ast::Symbol(span, x) => Ok(SimplExpr::VarRef(span.into(), x)),
|
||||
Ast::Literal(span, x) => Ok(SimplExpr::Literal(span.into(), x)),
|
||||
Ast::SimplExpr(span, x) => Ok(x),
|
||||
_ => Err(AstError::NotAValue(Some(e.span()), e.expr_type())),
|
||||
_ => Err(AstError::NotAValue(e.span(), e.expr_type())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
14
src/util.rs
14
src/util.rs
|
@ -1,14 +0,0 @@
|
|||
pub fn parse_duration(s: &str) -> anyhow::Result<std::time::Duration> {
|
||||
use std::time::Duration;
|
||||
if s.ends_with("ms") {
|
||||
Ok(Duration::from_millis(s.trim_end_matches("ms").parse()?))
|
||||
} else if s.ends_with('s') {
|
||||
Ok(Duration::from_secs(s.trim_end_matches('s').parse()?))
|
||||
} else if s.ends_with('m') {
|
||||
Ok(Duration::from_secs(s.trim_end_matches('m').parse::<u64>()? * 60))
|
||||
} else if s.ends_with('h') {
|
||||
Ok(Duration::from_secs(s.trim_end_matches('h').parse::<u64>()? * 60 * 60))
|
||||
} else {
|
||||
Err(anyhow::anyhow!("Failed to parse duration `{}`", s))
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue