DQU2N7ILDGRDL7JDAJ2RBE2R5IIM4D7A7A4MKKCA5YJQUKOZE4HAC
use super::*;
#[test]
fn decode_fb() -> miette::Result<()> {
let input = r#"
facebook name="abc"
facebook name=null id=1234
"#;
assert_eq!(
vec![
Facebook {
account: Account {
name: Some("abc".into()),
id: None
}
},
Facebook {
account: Account {
id: Some(1234),
name: None
}
}
],
knuffel::parse::<Vec<Facebook>>("", input).unwrap()
);
Ok(())
}
#[test]
fn where_am_i() -> miette::Result<()> {
let input = r#"
hdhoang "hdhoang.space" {
pat name="hdhoang"
fb name="hdh0000"
twt name="2125" id=21_25
} "#;
assert_eq!(
knuffel::parse::<Vec<Art>>("", input)?,
vec![Art {
handle: "hdhoang".into(),
web: Some("hdhoang.space".into()),
link_list: None,
pat: Some(Patreon {
per_month: 0,
account: Account {
name: Some("hdhoang".into()),
id: None
}
}),
fb: Some(Facebook {
account: Account {
name: Some("hdh0000".into()),
id: None
}
}),
twt: Some(Twitter {
account: Account {
name: Some("2125".into()),
id: Some(2125)
}
})
}]
);
Ok(())
}
let accounts = knuffel::parse::<Vec<Art>>(
"example.kdl",
r#"/-twitter name="abcde"
/-twitter id=1235
art "oglaf" (url)"oglaf.com" {
patreon "oglaf" null 0
facebook null
twitter "Oglaf"
}
"#,
)?;
let text = std::fs::read_to_string(FILE_NAME).into_diagnostic()?;
let accounts = knuffel::parse::<Vec<Art>>(FILE_NAME, &text)?;
#[derive(Debug, knuffel::Decode)]
#[cfg_attr(test, derive(PartialEq))]
pub struct Art {
/// prominent web handle
#[knuffel(node_name)]
handle: Name,
/// official website, if any
#[knuffel(argument, default)]
web: Option<Website>,
/// linktr.ee, carrd.co, ... and the like
#[knuffel(property, default)]
link_list: Option<Website>,
#[knuffel(child)]
pat: Option<Patreon>,
#[knuffel(child)]
kofi: Option<Kofi>,
#[knuffel(child)]
fb: Option<Facebook>,
#[knuffel(child)]
twt: Option<Twitter>,
}
pub type Name = String;
pub type Id = u64;
pub type Website = String;
/// name-or-id common pattern
#[derive(Debug, Default, knuffel::Decode)]
#[cfg_attr(test, derive(PartialEq))]
pub struct Account {
#[knuffel(property)]
name: Option<Name>,
#[knuffel(property, default)]
id: Option<Id>,
}
/// patreon profile, and monthly support amount
#[derive(Debug, knuffel::Decode)]
#[cfg_attr(test, derive(PartialEq))]
pub struct Patreon {
#[knuffel(property, default)]
per_month: u8,
#[knuffel(flatten(property))]
account: Account,
}
/// ko-fi profile, and monthly support amount
#[derive(Debug, knuffel::Decode)]
#[cfg_attr(test, derive(PartialEq))]
pub struct Kofi {
#[knuffel(property, default)]
per_month: u8,
#[knuffel(flatten(property))]
account: Account,
}
pub use self::art::*;
/// fb profile
#[derive(Debug, knuffel::Decode)]
#[cfg_attr(test, derive(PartialEq))]
pub struct Facebook {
#[knuffel(flatten(property))]
account: Account,
}
impl ToString for Facebook {
fn to_string(&self) -> String {
self.account
.id
.map(|n| format!("https://facebook.com/profile?id={n}"))
.or(self.account.name.clone())
.map(|n| format!("https://fb.me/{n}"))
.expect("both snowflake and username are missing")
}
}
/// twt/X profile
#[derive(Debug, knuffel::Decode)]
#[cfg_attr(test, derive(PartialEq))]
pub struct Twitter {
#[knuffel(flatten(property))]
account: Account,
}
impl ToString for Twitter {
fn to_string(&self) -> String {
self.account
.id
.map(|n| format!("https://x.com/i/user/{n}"))
.or(self.account.name.clone())
.map(|n| format!("https://x.com/{n}"))
.expect("both snowflake and username are missing")
}
}
mod art;
art "oglaf" "oglaf.com" {
facebook "oglaf"
huginn
twt
sereinde {
}
othatsraspberry {
}
alisa-pika {
ig "alisa.pika"
}
oglaf "oglaf.com" {
fb name="oglaf"
huginn 24
twt name="oglaf"
}
buttersafe "buttersafe.com" {
huginn 54
smbc {
yahtzee "https://fullyramblomatic.blogspot.com/" {
feed 8 "https://fullyramblomatic.blogspot.com/feed/default/posts"
yt "SecondWindGroup"
pat per-month=1 name="SecondWindGroup"
}
smbc "https://www.smbc-comics.com/" {
feed 3 "https://www.smbc-comics.com/comic/rss"
dilbert "https://scottadams.locals.com/" {
twt name="ScottAdamsSays"
huginn 42
}