mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-07-07 20:06:36 +02:00
Use error_chain
This commit is contained in:
parent
f9d950e621
commit
1272acb893
7 changed files with 169 additions and 73 deletions
51
Cargo.lock
generated
51
Cargo.lock
generated
|
@ -1,3 +1,34 @@
|
|||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace-sys"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.6"
|
||||
|
@ -8,6 +39,14 @@ dependencies = [
|
|||
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "error-chain"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.43"
|
||||
|
@ -31,6 +70,7 @@ name = "rask"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uuid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -39,6 +79,11 @@ name = "redox_syscall"
|
|||
version = "0.1.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.40"
|
||||
|
@ -74,11 +119,17 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
|
||||
"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0"
|
||||
"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
|
||||
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
|
||||
"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878"
|
||||
"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02"
|
||||
"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
|
||||
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
|
||||
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
|
||||
"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
|
||||
"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395"
|
||||
"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
|
||||
"checksum uuid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dab5c5526c5caa3d106653401a267fed923e7046f35895ffcb5ca42db64942e6"
|
||||
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
|
||||
|
|
|
@ -9,3 +9,4 @@ authors = ["Dustin J. Mitchell <dustin@mozilla.com>"]
|
|||
#indicatif = "0.9.0"
|
||||
uuid = "0.7"
|
||||
chrono = "0.4"
|
||||
error-chain = "0.12.0"
|
||||
|
|
9
src/errors.rs
Normal file
9
src/errors.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
error_chain!{
|
||||
foreign_links {
|
||||
Io(::std::io::Error);
|
||||
StrFromUtf8(::std::str::Utf8Error);
|
||||
StringFromUtf8(::std::string::FromUtf8Error);
|
||||
StringFromUtf16(::std::string::FromUtf16Error);
|
||||
}
|
||||
|
||||
}
|
12
src/main.rs
12
src/main.rs
|
@ -1,15 +1,23 @@
|
|||
extern crate chrono;
|
||||
extern crate uuid;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
mod tdb2;
|
||||
mod task;
|
||||
mod errors;
|
||||
|
||||
use tdb2::parse;
|
||||
use std::io::stdin;
|
||||
|
||||
fn main() {
|
||||
use errors::*;
|
||||
|
||||
quick_main!(run);
|
||||
|
||||
fn run() -> Result<()> {
|
||||
let input = stdin();
|
||||
parse(input.lock()).unwrap().iter().for_each(|t| {
|
||||
parse(input.lock())?.iter().for_each(|t| {
|
||||
println!("{:?}", t);
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
|
133
src/tdb2/ff4.rs
133
src/tdb2/ff4.rs
|
@ -1,38 +1,38 @@
|
|||
use std::str;
|
||||
use std::io::{Result, Error, ErrorKind};
|
||||
|
||||
use super::pig::Pig;
|
||||
use task::{TaskBuilder, Task};
|
||||
use errors::*;
|
||||
|
||||
/// Rust implementation of part of utf8_codepoint from Taskwarrior's src/utf8.cpp
|
||||
///
|
||||
/// Note that the original function will return garbage for invalid hex sequences;
|
||||
/// this panics instead.
|
||||
fn hex_to_unicode(value: &[u8]) -> String {
|
||||
fn hex_to_unicode(value: &[u8]) -> Result<String> {
|
||||
if value.len() < 4 {
|
||||
panic!(format!("unicode escape too short -- {:?}", value));
|
||||
bail!(format!("too short"));
|
||||
}
|
||||
|
||||
fn nyb(c: u8) -> u16 {
|
||||
fn nyb(c: u8) -> Result<u16> {
|
||||
match c {
|
||||
b'0'...b'9' => (c - b'0') as u16,
|
||||
b'a'...b'f' => (c - b'a' + 10) as u16,
|
||||
b'A'...b'F' => (c - b'A' + 10) as u16,
|
||||
_ => panic!(format!("invalid hex character {:?}", c)),
|
||||
b'0'...b'9' => Ok((c - b'0') as u16),
|
||||
b'a'...b'f' => Ok((c - b'a' + 10) as u16),
|
||||
b'A'...b'F' => Ok((c - b'A' + 10) as u16),
|
||||
_ => bail!("invalid hex character"),
|
||||
}
|
||||
};
|
||||
|
||||
let words = [
|
||||
nyb(value[0]) << 12 | nyb(value[1]) << 8 | nyb(value[2]) << 4 | nyb(value[3]),
|
||||
nyb(value[0])? << 12 | nyb(value[1])? << 8 | nyb(value[2])? << 4 | nyb(value[3])?,
|
||||
];
|
||||
return String::from_utf16(&words[..]).unwrap();
|
||||
Ok(String::from_utf16(&words[..])?)
|
||||
}
|
||||
|
||||
/// Rust implementation of JSON::decode in Taskwarrior's src/JSON.cpp
|
||||
///
|
||||
/// Decode the given byte slice into a string using Taskwarrior JSON's escaping The slice is
|
||||
/// assumed to be ASCII; unicode escapes within it will be expanded.
|
||||
fn json_decode(value: &[u8]) -> String {
|
||||
fn json_decode(value: &[u8]) -> Result<String> {
|
||||
let length = value.len();
|
||||
let mut rv = String::with_capacity(length);
|
||||
|
||||
|
@ -54,7 +54,14 @@ fn json_decode(value: &[u8]) -> String {
|
|||
b'r' => rv.push('\r' as char),
|
||||
b't' => rv.push('\t' as char),
|
||||
b'u' => {
|
||||
rv.push_str(&hex_to_unicode(&value[pos + 1..]));
|
||||
let unicode = hex_to_unicode(&value[pos + 1..pos + 5]).chain_err(|| {
|
||||
let esc = &value[pos - 1..pos + 5];
|
||||
match str::from_utf8(esc) {
|
||||
Ok(s) => format!("invalid unicode escape `{}`", s),
|
||||
Err(_) => format!("invalid unicode escape bytes {:?}", esc),
|
||||
}
|
||||
})?;
|
||||
rv.push_str(&unicode);
|
||||
pos += 4;
|
||||
}
|
||||
_ => {
|
||||
|
@ -68,7 +75,7 @@ fn json_decode(value: &[u8]) -> String {
|
|||
pos += 1;
|
||||
}
|
||||
|
||||
rv
|
||||
Ok(rv)
|
||||
}
|
||||
|
||||
/// Rust implementation of Task::decode in Taskwarrior's src/Task.cpp
|
||||
|
@ -89,37 +96,25 @@ pub(super) fn parse_ff4(line: &str) -> Result<Task> {
|
|||
let mut pig = Pig::new(line.as_bytes());
|
||||
let mut builder = TaskBuilder::new();
|
||||
|
||||
if !pig.skip(b'[') {
|
||||
return Err(Error::new(ErrorKind::Other, "bad line"));
|
||||
}
|
||||
if let Some(line) = pig.get_until(b']') {
|
||||
let mut pig = Pig::new(line);
|
||||
while !pig.depleted() {
|
||||
if let Some(name) = pig.get_until(b':') {
|
||||
let name = str::from_utf8(name).unwrap();
|
||||
if !pig.skip(b':') {
|
||||
return Err(Error::new(ErrorKind::Other, "bad line"));
|
||||
}
|
||||
if let Some(value) = pig.get_quoted(b'"') {
|
||||
let value = json_decode(value);
|
||||
let value = decode(value);
|
||||
builder = builder.set(name, value);
|
||||
} else {
|
||||
return Err(Error::new(ErrorKind::Other, "bad line"));
|
||||
}
|
||||
pig.skip(b' ');
|
||||
} else {
|
||||
return Err(Error::new(ErrorKind::Other, "bad line"));
|
||||
}
|
||||
pig.skip(b'[')?;
|
||||
let line = pig.get_until(b']')?;
|
||||
let mut subpig = Pig::new(line);
|
||||
while !subpig.depleted() {
|
||||
let name = subpig.get_until(b':')?;
|
||||
let name = str::from_utf8(name)?;
|
||||
subpig.skip(b':')?;
|
||||
if let Some(value) = subpig.get_quoted(b'"') {
|
||||
let value = json_decode(value)?;
|
||||
let value = decode(value);
|
||||
builder = builder.set(name, value);
|
||||
} else {
|
||||
bail!("bad line 3");
|
||||
}
|
||||
} else {
|
||||
return Err(Error::new(ErrorKind::Other, "bad line"));
|
||||
}
|
||||
if !pig.skip(b']') {
|
||||
return Err(Error::new(ErrorKind::Other, "bad line"));
|
||||
subpig.skip(b' ').ok(); // ignore if not found..
|
||||
}
|
||||
pig.skip(b']')?;
|
||||
if !pig.depleted() {
|
||||
return Err(Error::new(ErrorKind::Other, "bad line"));
|
||||
bail!("bad line 5");
|
||||
}
|
||||
Ok(builder.finish())
|
||||
}
|
||||
|
@ -131,77 +126,96 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_hex_to_unicode_digits() {
|
||||
assert_eq!(hex_to_unicode(b"1234"), "\u{1234}");
|
||||
assert_eq!(hex_to_unicode(b"1234").unwrap(), "\u{1234}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hex_to_unicode_lower() {
|
||||
assert_eq!(hex_to_unicode(b"abcd"), "\u{abcd}");
|
||||
assert_eq!(hex_to_unicode(b"abcd").unwrap(), "\u{abcd}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hex_to_unicode_upper() {
|
||||
assert_eq!(hex_to_unicode(b"ABCD"), "\u{abcd}");
|
||||
assert_eq!(hex_to_unicode(b"ABCD").unwrap(), "\u{abcd}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hex_to_unicode_too_short() {
|
||||
assert!(hex_to_unicode(b"AB").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hex_to_unicode_invalid() {
|
||||
assert!(hex_to_unicode(b"defg").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_decode_no_change() {
|
||||
assert_eq!(json_decode(b"abcd"), "abcd");
|
||||
assert_eq!(json_decode(b"abcd").unwrap(), "abcd");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_decode_escape_quote() {
|
||||
assert_eq!(json_decode(b"ab\\\"cd"), "ab\"cd");
|
||||
assert_eq!(json_decode(b"ab\\\"cd").unwrap(), "ab\"cd");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_decode_escape_backslash() {
|
||||
assert_eq!(json_decode(b"ab\\\\cd"), "ab\\cd");
|
||||
assert_eq!(json_decode(b"ab\\\\cd").unwrap(), "ab\\cd");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_decode_escape_frontslash() {
|
||||
assert_eq!(json_decode(b"ab\\/cd"), "ab/cd");
|
||||
assert_eq!(json_decode(b"ab\\/cd").unwrap(), "ab/cd");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_decode_escape_b() {
|
||||
assert_eq!(json_decode(b"ab\\bcd"), "ab\x08cd");
|
||||
assert_eq!(json_decode(b"ab\\bcd").unwrap(), "ab\x08cd");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_decode_escape_f() {
|
||||
assert_eq!(json_decode(b"ab\\fcd"), "ab\x0ccd");
|
||||
assert_eq!(json_decode(b"ab\\fcd").unwrap(), "ab\x0ccd");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_decode_escape_n() {
|
||||
assert_eq!(json_decode(b"ab\\ncd"), "ab\ncd");
|
||||
assert_eq!(json_decode(b"ab\\ncd").unwrap(), "ab\ncd");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_decode_escape_r() {
|
||||
assert_eq!(json_decode(b"ab\\rcd"), "ab\rcd");
|
||||
assert_eq!(json_decode(b"ab\\rcd").unwrap(), "ab\rcd");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_decode_escape_t() {
|
||||
assert_eq!(json_decode(b"ab\\tcd"), "ab\tcd");
|
||||
assert_eq!(json_decode(b"ab\\tcd").unwrap(), "ab\tcd");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_decode_escape_other() {
|
||||
assert_eq!(json_decode(b"ab\\xcd"), "ab\\xcd");
|
||||
assert_eq!(json_decode(b"ab\\xcd").unwrap(), "ab\\xcd");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_decode_escape_eos() {
|
||||
assert_eq!(json_decode(b"ab\\"), "ab\\");
|
||||
assert_eq!(json_decode(b"ab\\").unwrap(), "ab\\");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_decode_escape_unicode() {
|
||||
assert_eq!(json_decode(b"ab\\u1234"), "ab\u{1234}");
|
||||
assert_eq!(json_decode(b"ab\\u1234").unwrap(), "ab\u{1234}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_decode_escape_unicode_bad() {
|
||||
let rv = json_decode(b"ab\\uwxyz");
|
||||
assert_eq!(
|
||||
rv.unwrap_err().to_string(),
|
||||
"invalid unicode escape `\\uwxyz`"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -225,4 +239,11 @@ mod test {
|
|||
assert_eq!(task.status, Pending);
|
||||
assert_eq!(task.description, "desc");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_ff4_fail() {
|
||||
assert!(parse_ff4("abc:10]").is_err());
|
||||
assert!(parse_ff4("[abc:10").is_err());
|
||||
assert!(parse_ff4("[abc:10 123:123]").is_err());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
mod pig;
|
||||
mod ff4;
|
||||
|
||||
use std::io::{BufRead, Result};
|
||||
use super::task::Task;
|
||||
use std::io::BufRead;
|
||||
use task::Task;
|
||||
use self::ff4::parse_ff4;
|
||||
use errors::*;
|
||||
|
||||
pub(super) fn parse(reader: impl BufRead) -> Result<Vec<Task>> {
|
||||
let mut tasks = vec![];
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
//! A minimal implementation of the "Pig" parsing utility from the Taskwarrior
|
||||
//! source.
|
||||
|
||||
use errors::*;
|
||||
|
||||
pub struct Pig<'a> {
|
||||
input: &'a [u8],
|
||||
cursor: usize,
|
||||
|
@ -14,9 +16,9 @@ impl<'a> Pig<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_until(&mut self, c: u8) -> Option<&'a [u8]> {
|
||||
pub fn get_until(&mut self, c: u8) -> Result<&'a [u8]> {
|
||||
if self.cursor >= self.input.len() {
|
||||
return None;
|
||||
return Err(Error::from("input truncated"));
|
||||
}
|
||||
|
||||
let mut i = self.cursor;
|
||||
|
@ -24,13 +26,13 @@ impl<'a> Pig<'a> {
|
|||
if self.input[i] == c {
|
||||
let rv = &self.input[self.cursor..i];
|
||||
self.cursor = i;
|
||||
return Some(rv);
|
||||
return Ok(rv);
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
let rv = &self.input[self.cursor..];
|
||||
self.cursor = self.input.len();
|
||||
Some(rv)
|
||||
Ok(rv)
|
||||
}
|
||||
|
||||
// TODO: get_until_str
|
||||
|
@ -104,12 +106,15 @@ impl<'a> Pig<'a> {
|
|||
return false;
|
||||
}
|
||||
|
||||
pub fn skip(&mut self, c: u8) -> bool {
|
||||
pub fn skip(&mut self, c: u8) -> Result<()> {
|
||||
if self.cursor < self.input.len() && self.input[self.cursor] == c {
|
||||
self.cursor += 1;
|
||||
return true;
|
||||
return Ok(());
|
||||
}
|
||||
false
|
||||
bail!(format!(
|
||||
"expected character `{}`",
|
||||
String::from_utf8(vec![c])?
|
||||
));
|
||||
}
|
||||
|
||||
// TODO: skip_all_one_of
|
||||
|
@ -142,21 +147,21 @@ mod test {
|
|||
fn test_get_until() {
|
||||
let s = b"abc:123";
|
||||
let mut pig = Pig::new(s);
|
||||
assert_eq!(pig.get_until(b':'), Some(&s[..3]));
|
||||
assert_eq!(pig.get_until(b':').unwrap(), &s[..3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_until_empty() {
|
||||
let s = b"abc:123";
|
||||
let mut pig = Pig::new(s);
|
||||
assert_eq!(pig.get_until(b'a'), Some(&s[..0]));
|
||||
assert_eq!(pig.get_until(b'a').unwrap(), &s[..0]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_until_not_found() {
|
||||
let s = b"abc:123";
|
||||
let mut pig = Pig::new(s);
|
||||
assert_eq!(pig.get_until(b'/'), Some(&s[..]));
|
||||
assert_eq!(pig.get_until(b'/').unwrap(), &s[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -251,7 +256,7 @@ mod test {
|
|||
fn test_skip_match() {
|
||||
let s = b"foo";
|
||||
let mut pig = Pig::new(s);
|
||||
assert!(pig.skip(b'f'));
|
||||
assert!(pig.skip(b'f').is_ok());
|
||||
assert_eq!(pig.get_until_eos(), Some(&s[1..]));
|
||||
}
|
||||
|
||||
|
@ -259,7 +264,7 @@ mod test {
|
|||
fn test_skip_no_match() {
|
||||
let s = b"foo";
|
||||
let mut pig = Pig::new(s);
|
||||
assert!(!pig.skip(b'x'));
|
||||
assert!(pig.skip(b'x').is_err());
|
||||
assert_eq!(pig.get_until_eos(), Some(&s[..]));
|
||||
}
|
||||
|
||||
|
@ -268,7 +273,7 @@ mod test {
|
|||
let s = b"foo";
|
||||
let mut pig = Pig::new(s);
|
||||
assert!(pig.skip_n(3));
|
||||
assert!(!pig.skip(b'x'));
|
||||
assert!(pig.skip(b'x').is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue