4.3 KiB
boxing_todo
Instructions
The objective is to create an API to parse a list of todos that are organized in a JSON file. You must handle all possible errors in a multiple error system.
Organization of the JSON file:
{
"title": "TODO LIST FOR PISCINE RUST",
"tasks": [
{ "id": 0, "description": "do this", "level": 0 },
{ "id": 1, "description": "do that", "level": 5 }
]
}
err.rs
Create a module in a file named err.rs which handles the boxing of errors.
This module must implement an enum
called ParseErr
which will take care of the parsing errors. It must have the following elements:
Empty
Malformed
: which has a dynamic boxed error as element
A structure called ReadErr
which will take care of the reading errors, with an element called child_err
of type Box<dyn Error>
.
For each data structure, you will have to implement a function called fmt
for the Display
trait. It should write the message "Fail to parse todo" in the case of any parsing error. Otherwise, it should write the message "Fail to read todo file".
For the Error
trait, the following functions (methods) have to be implemented:
-
source
which returns anOption
with the error:- For the
ReadErr
, it must return the option with the error. - For the
ParseErr
, it will return an option which isNone
if the tasks are empty, and the error if the parsing is malformed.
- For the
lib.rs
In the lib file you will have to implement a function called get_todo
which receives a string and returns a Result
which can be the structure TodoList
or a boxing error. This function must be able to deserialize the json file.
Basically it must parse and read the JSON file and return the TodoList
if everything is fine, otherwise it returns the error.
Expected Functions
For err.rs
use std::fmt;
use std::fmt::Display;
use std::error::Error;
pub enum ParseErr {
// expected public fields
}
// required by error trait
impl Display for ParseErr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
pub struct ReadErr {
// expected public fields
}
// required by error trait
impl Display for ReadErr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
impl Error for ParseErr {
fn source(&self) -> Option<&(dyn Error + 'static)> {
}
}
impl Error for ReadErr {
fn source(&self) -> Option<&(dyn Error + 'static)> {
}
}
for lib.rs
mod err;
use err::{ ParseErr, ReadErr };
pub use json::{parse, stringify};
pub use std::error::Error;
#[derive(Debug, Eq, PartialEq)]
pub struct Task {
pub id: u32,
pub description: String,
pub level: u32,
}
#[derive(Debug, Eq, PartialEq)]
pub struct TodoList {
pub title: String,
pub tasks: Vec<Task>,
}
impl TodoList {
pub fn get_todo(path: &str) -> Result<TodoList, Box<dyn Error>> {
}
}
Usage
Here is a program to test your function.
You can create some todos yourself, inside the boxing_todo file in order to test it. The JSON structure can be found above.
use boxing_todo::TodoList;
fn main() {
let todos = TodoList::get_todo("todo.json");
match todos {
Ok(list) => println!("{:?}", list),
Err(e) => {
println!("{}{:?}", e.to_string(), e.source());
}
}
let todos = TodoList::get_todo("todo_empty.json");
match todos {
Ok(list) => println!("{:?}", list),
Err(e) => {
println!("{}{:?}", e.to_string(), e.source());
}
}
let todos = TodoList::get_todo("malformed_object.json");
match todos {
Ok(list) => println!("{:?}", list),
Err(e) => {
println!("{}{:?}", e.to_string(), e.source());
}
}
}
And its output:
$ cargo run
TodoList { title: "TODO LIST FOR PISCINE RUST", tasks: [Task { id: 0, description: "do this", level: 0 }, Task { id: 1, description: "do that", level: 5 }] }
Fail to parses todoNone
Fail to parse todo Some(Malformed(UnexpectedCharacter { ch: ',', line: 2, column: 18 }))
$