use crate::pinboard::Tag;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
type StdResult<T, E> = std::result::Result<T, E>;
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct Target {
read_later: bool,
send_to_insty: bool,
tags: Vec<Tag>,
}
impl std::fmt::Display for Target {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> StdResult<(), std::fmt::Error> {
write!(
f,
"(Read Later: {}, Instapaper: {}, Tags: {})",
self.read_later,
self.send_to_insty,
match self
.tags
.iter()
.map(|tag| format!("{}", tag))
.reduce(|accum, item| format!("{}, {}", accum, item))
{
Some(s) => String::from(&s[0..12]),
None => String::from("(none)"),
}
)
}
}
impl Target {
pub fn get_tags(&self) -> std::slice::Iter<'_, Tag> {
self.tags.iter()
}
pub fn read_later(&self) -> bool {
self.read_later
}
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct Config {
#[serde(default)]
version: u32,
token: Option<String>,
targets: Option<HashMap<String, Target>>,
#[serde(rename = "username")]
insty_username: Option<String>,
#[serde(rename = "password")]
insty_password: Option<String>,
}
impl Config {
pub fn token(&self) -> Option<&String> {
self.token.as_ref()
}
pub fn get_target(&self, name: &str) -> Option<&Target> {
self.targets.as_ref().and_then(|targets| targets.get(name))
}
}
#[cfg(test)]
pub mod test {
use super::*;
#[test]
fn config_smoke() {
let s = format!("{}", Target::default());
assert_eq!(s, "(Read Later: false, Instapaper: false, Tags: (none))");
let _cfg: Config = toml::from_str(
"username = \"jdoe@hotmail.com\"
[targets]
[targets.1]
tags = [\"@review\", \"news\"]
read_later = true
send_to_insty = true
",
)
.unwrap();
}
}