// todolist_parser/examples/basics.rs
extern crate todolist_parser;
use todolist_parser::TodoList;
fn main() {
let todos = TodoList::get_todos("examples/todos");
match todos {
Ok(list) => println!("{:?}", list),
Err(e) => {
println!("{}", e.description());
println!("{:?}", e)
}
}
}
// todolist_parser/src/error.rs
use std::error::Error;
use std::fmt;
use std::fmt::Display;
#[derive(Debug)]
pub enum ParseErr {
Malformed,
Empty
}
#[derive(Debug)]
pub struct ReadErr {
pub child_err: Box<dyn Error>
}
// Required by error trait
impl Display for ReadErr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Failed reading todo file")
}
}
// Required by error trait
impl Display for ParseErr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Todo list parsing failed")
}
}
impl Error for ReadErr {
fn description(&self) -> &str {
"Todolist read failed: "
}
fn cause(&self) -> Option<&dyn Error> {
Some(&*self.child_err)
}
}
impl Error for ParseErr {
fn description(&self) -> &str {
"Todolist parse failed: "
}
fn cause(&self) -> Option<&Error> {
None
}
}
// todolist_parser/src/lib.rs
//! This crate provides an API to parse list of todos
use std::fs::read_to_string;
use std::path::Path;
mod error;
use error::ParseErr;
use error::ReadErr;
use std::error::Error;
/// This struct contains a list of todos parsed as a Vec<String>
#[derive(Debug)]
pub struct TodoList {
tasks: Vec<String>,
}
impl TodoList {
pub fn get_todos<P>(path: P) -> Result<TodoList, Box<dyn Error>>
where
P: AsRef<Path>, {
let read_todos: Result<String, Box<dyn Error>> = read_todos(path);
let parsed_todos = parse_todos(&read_todos?)?;
Ok(parsed_todos)
}
}
pub fn read_todos<P>(path: P) -> Result<String, Box<dyn Error>>
where
P: AsRef<Path>,
{
let raw_todos = read_to_string(path)
.map_err(|e| ReadErr {
child_err: Box::new(e),
})?;
Ok(raw_todos)
}
pub fn parse_todos(todo_str: &str) -> Result<TodoList, Box<dyn Error>> {
let mut tasks: Vec<String> = vec![];
for i in todo_str.lines() {
tasks.push(i.to_string());
}
if tasks.is_empty() {
Err(ParseErr::Empty.into())
} else {
Ok(TodoList { tasks })
}
}
本文暂时没有评论,来添加一个吧(●'◡'●)