Make extracting config values from toml struct more elegant with 'and_then' and 'map' on option types + extract authors from config file

This commit is contained in:
Mathieu David 2016-02-22 15:57:29 +01:00
parent bb486c02b8
commit 371336746f
1 changed files with 46 additions and 29 deletions

View File

@ -55,6 +55,7 @@ use std::error::Error;
use utils; use utils;
#[derive(Debug, Clone)]
pub struct Config { pub struct Config {
title: String, title: String,
description: String, description: String,
@ -72,22 +73,26 @@ pub struct Config {
plugins: Vec<Plugin>, plugins: Vec<Plugin>,
} }
#[derive(Debug, Clone)]
pub struct Author { pub struct Author {
name: String, name: String,
email: Option<String>, email: Option<String>,
} }
#[derive(Debug, Clone)]
pub struct Output { pub struct Output {
identifier: String, identifier: String,
destination: PathBuf, destination: PathBuf,
config: Option<toml::Table>, config: Option<toml::Table>,
} }
#[derive(Debug, Clone)]
pub struct Language { pub struct Language {
name: String, name: String,
code: String, code: String,
} }
#[derive(Debug, Clone)]
pub struct Plugin { pub struct Plugin {
identifier: String, identifier: String,
enabled: bool, enabled: bool,
@ -166,6 +171,8 @@ impl Config {
.and_then(|s| source_path_from_toml(&s)) .and_then(|s| source_path_from_toml(&s))
.unwrap_or(PathBuf::from("src/")); .unwrap_or(PathBuf::from("src/"));
self.authors = authors_from_toml(&config);
Ok(()) Ok(())
} }
@ -263,11 +270,11 @@ impl Author {
/// #extern crate mdbook; /// #extern crate mdbook;
/// # /// #
/// #fn main() { /// #fn main() {
/// let author = mdbook::config::Author::new("John Doe").set_email("john@doe.org"); /// let author = mdbook::config::Author::new("John Doe").set_email(Some("john@doe.org"));
/// #} /// #}
/// ///
pub fn set_email(mut self, email: &str) -> Self { pub fn set_email(mut self, email: Option<&str>) -> Self {
self.email = Some(String::from(email)); self.email = email.map(|s| String::from(s));
self self
} }
@ -368,43 +375,50 @@ impl Plugin {
// Helper functions to extract values from toml // Helper functions to extract values from toml
fn title_from_toml(toml: &toml::Table) -> Option<String> { fn title_from_toml(toml: &toml::Table) -> Option<String> {
if let Some(value) = toml.get("title") { toml.get("title")
if let Some(title) = value.as_str() { .and_then(|v| v.as_str())
return Some(String::from(title)) .map(|v| v.to_owned())
}
}
None
} }
fn description_from_toml(toml: &toml::Table) -> Option<String> { fn description_from_toml(toml: &toml::Table) -> Option<String> {
if let Some(value) = toml.get("description") { toml.get("description")
if let Some(description) = value.as_str() { .and_then(|v| v.as_str())
return Some(String::from(description)) .map(|v| v.to_owned())
}
}
None
} }
fn source_from_toml(toml: &toml::Table) -> Option<toml::Table> { fn source_from_toml(toml: &toml::Table) -> Option<toml::Table> {
if let Some(value) = toml.get("source") { toml.get("source")
if let Some(source) = value.as_table() { .and_then(|v| v.as_table())
return Some(source.to_owned()) .map(|v| v.to_owned())
}
}
None
} }
fn source_path_from_toml(source: &toml::Table) -> Option<PathBuf> { fn source_path_from_toml(source: &toml::Table) -> Option<PathBuf> {
if let Some(value) = source.get("path") { source.get("path")
if let Some(path) = value.as_str() { .and_then(|v| v.as_str())
return Some(PathBuf::from(path)) .map(|v| PathBuf::from(v))
}
} }
None fn authors_from_toml(toml: &toml::Table) -> Vec<Author> {
let array = toml.get("author")
.and_then(|v| v.as_slice())
.unwrap_or(&[]);
let mut authors: Vec<Author> = vec![];
for author in array {
let author = if let Some(t) = author.as_table() { t } else { continue };
let name = author.get("name")
.and_then(|v| v.as_str())
.unwrap_or("Anonymous");
let email = author.get("email")
.and_then(|v| v.as_str());
authors.push(Author::new(name).set_email(email));
}
authors
} }
@ -471,6 +485,8 @@ rust-playpen = { enabled = true }
assert_eq!(config.title(), "mdBook"); assert_eq!(config.title(), "mdBook");
assert_eq!(config.description(), "This is a command line utility to generate books from markdown files"); assert_eq!(config.description(), "This is a command line utility to generate books from markdown files");
assert_eq!(config.source(), PathBuf::from("custom_source/")); assert_eq!(config.source(), PathBuf::from("custom_source/"));
assert_eq!(config.authors()[0].name, "Mathieu David".to_owned());
assert_eq!(config.authors()[0].email, Some("mathieudavid@mathieudavid.org".to_owned()));
} }
@ -485,5 +501,6 @@ rust-playpen = { enabled = true }
assert_eq!(config.title(), "Book"); assert_eq!(config.title(), "Book");
assert_eq!(config.description(), ""); assert_eq!(config.description(), "");
assert_eq!(config.source(), PathBuf::from("src/")); assert_eq!(config.source(), PathBuf::from("src/"));
assert!(config.authors().is_empty());
} }
} }