Skip to content

Commit

Permalink
Merge pull request #48 from baoyachi/issue/47
Browse files Browse the repository at this point in the history
fix partial_input output is too long and needs to be truncated
  • Loading branch information
baoyachi authored Jun 4, 2024
2 parents c71fd26 + 23277a9 commit dc713b1
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 10 deletions.
1 change: 1 addition & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ jobs:

- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
if: ${{github.ref == 'refs/heads/master' }}
with:
personal_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./playground/site/dist
Expand Down
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ readme = "README.md"
categories = ["parsing", "date-and-time"]
repository = "https://github.com/baoyachi/duration-str"
license = "Apache-2.0"
exclude = ["./playground"]
exclude = ["duration-str.png", "./playground"]

[features]
default = ["chrono", "serde", "time"]

[dependencies]
thiserror = "1.0.37"
chrono = { version = "0.4.38", optional = true }
time = { version = "0.3.17", optional = true }
chrono = { version = "0.4.38", optional = true, default-features = false, features = ["now"] }
time = { version = "0.3.17", optional = true, default-features = false }

serde = { version = "1.0.147", features = ["derive"], optional = true }
serde = { version = "1.0.147", features = ["derive"], optional = true}
rust_decimal = { version = "1.29.1", default-features = false }
winnow = "0.6.8"

Expand Down
Binary file added duration-str.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 65 additions & 2 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
use std::fmt::{Display, Formatter};
use std::fmt::{Debug, Display, Formatter};
use thiserror::Error;
use winnow::error::{ErrorKind, FromExternalError, ParserError};
use winnow::stream::Stream;

pub trait RawDebug {
fn raw(&self) -> String;
}

impl<A> RawDebug for A
where
A: AsRef<str>,
{
fn raw(&self) -> String {
self.as_ref().to_string()
}
}

#[derive(Error, Debug, PartialEq)]
pub enum DError {
#[error("{0}")]
Expand All @@ -11,9 +24,11 @@ pub enum DError {
OverflowError,
}

const PARTIAL_INPUT_MAX_LEN: usize = 11;

#[derive(Debug, PartialEq, Eq)]
pub struct PError<I> {
pub partial_input: I,
partial_input: I,
kind: ErrorKind,
cause: String,
}
Expand All @@ -31,6 +46,22 @@ impl<I> PError<I> {
self.cause = cause.as_ref().to_string();
self
}

pub fn partial_input(&self) -> String
where
I: RawDebug,
{
let raw = self.partial_input.raw();
if let Some(offset) = raw
.char_indices()
.enumerate()
.find_map(|(pos, (offset, _))| (PARTIAL_INPUT_MAX_LEN <= pos).then_some(offset))
{
format!("{}...", raw.split_at(offset).0)
} else {
raw
}
}
}

impl<I: Stream + Clone> ParserError<I> for PError<I> {
Expand Down Expand Up @@ -66,3 +97,35 @@ where
Ok(())
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_partial_input() {
let error = PError::new("1234567890abcde", ErrorKind::Complete);
let partial_input = error.partial_input();
assert_eq!(partial_input, "1234567890a...");

let error = PError::new("你好,龙骧虎步龙行龘龘龘", ErrorKind::Complete);
let partial_input = error.partial_input();
assert_eq!(partial_input, "你好,龙骧虎步龙行龘龘...");

let error = PError::new("hello,你好", ErrorKind::Complete);
let partial_input = error.partial_input();
assert_eq!(partial_input, "hello,你好");

let error = PError::new("1mins", ErrorKind::Complete);
let partial_input = error.partial_input();
assert_eq!(partial_input, "1mins");

let error = PError::new("MILLISECONDhah", ErrorKind::Complete);
let partial_input = error.partial_input();
assert_eq!(partial_input, "MILLISECOND...");

let error = PError::new("MILLISECOND", ErrorKind::Complete);
let partial_input = error.partial_input();
assert_eq!(partial_input, "MILLISECOND");
}
}
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#![doc(
html_logo_url = "https://raw.githubusercontent.com/baoyachi/duration-rs/master/duration-str.png"
)]
//! Parse string to `Duration` .
//!
//! The String value unit support for one of:["y","mon","w","d","h","m","s", "ms", "µs", "ns"]
Expand Down
4 changes: 2 additions & 2 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ fn cond_unit1<'a>(input: &mut &'a str) -> PResult<CondUnit, PError<&'a str>> {
}

fn opt_cond_unit<'a>(input: &mut &'a str) -> PResult<CondUnit, PError<&'a str>> {
let multispace = multispace0::<_, PError<_>>;
let result = cond_unit1
.parse_next(input)
.map_err(|err: ErrMode<PError<_>>| {
err.map(|x| {
let partial_input = x.partial_input;
let partial_input = x.partial_input();
x.append_cause(CondUnit::expect_err(partial_input))
})
});
if result.is_err() {
let multispace = multispace0::<_, PError<_>>;
if (multispace, eof).parse_next(input).is_ok() {
// The input result is empty except for spaces. Give `TimeUnit` default value
return Ok(CondUnit::Plus);
Expand Down
4 changes: 2 additions & 2 deletions src/unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ pub(crate) fn unit_abbr1<'a>(input: &mut &'a str) -> PResult<TimeUnit, PError<&'
.parse_next(input)
.map_err(|err: ErrMode<PError<_>>| {
err.map(|x| {
let partial_input = x.partial_input;
let partial_input = x.partial_input();
x.append_cause(TimeUnit::expect_err(partial_input))
})
})?;
Expand All @@ -121,9 +121,9 @@ pub(crate) fn unit_abbr1<'a>(input: &mut &'a str) -> PResult<TimeUnit, PError<&'
}

pub(crate) fn opt_unit_abbr<'a>(input: &mut &'a str) -> PResult<TimeUnit, PError<&'a str>> {
let multispace = multispace0::<_, PError<_>>;
let result = unit_abbr1(input);
if result.is_err() {
let multispace = multispace0::<_, PError<_>>;
if (multispace, eof).parse_next(input).is_ok() {
// The input result is empty except for spaces. Give `TimeUnit` default value
return Ok(TimeUnit::default());
Expand Down

0 comments on commit dc713b1

Please sign in to comment.