powerset-enum 0.1.0

A poor man's anonymous enum
Documentation
use std::path::Path;

use std::fs;
use std::io;

use serde_derive::Deserialize;

#[derive(Debug, err_derive::Error)]
#[error(display = "field is out of range")]
struct FieldError;

#[derive(Debug, err_derive::Error)]
enum Error {
    #[error(display = "{}", _0)]
    IoError(io::Error),
    #[error(display = "{}", _0)]
    JsonError(serde_json::Error),
    #[error(display = "{}", _0)]
    FieldError(FieldError),
}

#[derive(Debug, Default, Deserialize)]
struct Data {
    field: u32,
}

fn load_data_file_unchecked(path: &Path) -> Result<Data, Error> {
    let file = fs::File::open(path).map_err(Error::IoError)?;
    serde_json::from_reader(file).map_err(Error::JsonError)
}

fn load_data_file(path: &Path) -> Result<Data, Error> {
    let data = load_data_file_unchecked(&path)?;
    if data.field < 20 {
        return Err(Error::FieldError(FieldError));
    }
    Ok(data)
}

fn load_data_file_or_default(path: &Path) -> Result<Data, Error> {
    load_data_file(path).or_else(|e| match e {
        Error::IoError(_) => Ok(Data::default()),
        e => Err(e),
    })
}

fn load_data_best_effort(path: &Path) -> Data {
    load_data_file_or_default(path).unwrap_or_else(|e| match e {
        Error::IoError(e) => panic!("IO error should have been impossible, but we got {}", e),
        Error::JsonError(_) => {
            let content =
                fs::read_to_string(&path).expect("we managed read it before - why not now?");
            if let Some(m) = regex::Regex::new(r"\d+").unwrap().find(&content) {
                Data {
                    field: m.as_str().parse().unwrap(),
                }
            } else {
                Data::default()
            }
        }
        Error::FieldError(_) => load_data_file_unchecked(path)
            .expect("we managed to read and parse it before - why not now?"),
    })
}

fn main() {
    let tempdir = tempfile::tempdir().unwrap();
    let good_file = tempdir.path().join("good.json");
    fs::write(&good_file, r#"
    {
        "field": 42
    }
    "#).unwrap();
    let bad_data = tempdir.path().join("bad-data.json");
    fs::write(&bad_data, r#"
    {
        "field": 120
    }
    "#).unwrap();
    let malformed = tempdir.path().join("malformed.json");
    fs::write(&malformed, r#"
    {
        "field": 23
    "#).unwrap();

    println!("Good file: {:?}", load_data_best_effort(&good_file));
    println!("Bad data: {:?}", load_data_best_effort(&bad_data));
    println!("Malformed: {:?}", load_data_best_effort(&malformed));
    println!("Nonexistant: {:?}", load_data_best_effort(Path::new("nonexistant.json")));
}