monetize_estate_side/pump/
config.rs1use std::collections::BTreeMap;
7use std::path::Path;
8use std::time::Duration;
9
10use serde::{Deserialize, Serialize};
11
12pub const CONFIG_REL: &str = "fleet/fleet.json";
14
15pub const FEED_FLEET: &str = "fleet";
16pub const FEED_FLEET_INSTANCE: &str = "fleet_instance";
17pub const FEED_FLEET_AT: &str = "fleet_at";
18pub const FEED_FLEET_CA: &str = "fleet_ca";
19pub const FEED_MONETIZE: &str = "monetize_pubkey";
20
21pub const DEFAULT_EVERY: Duration = Duration::from_secs(30);
23
24#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
25#[serde(default)]
26pub struct FleetConfig {
27 pub url: String,
29 pub at: Option<String>,
31 pub ca_pem: Option<String>,
33 pub instance: String,
35 pub role: String,
37 pub monetize_pubkey: String,
39}
40
41impl FleetConfig {
42 pub fn from_feed(feed: &BTreeMap<String, String>) -> Option<FleetConfig> {
44 let get = |k: &str| {
45 feed.get(k).map(|v| v.trim().to_string()).filter(|v| !v.is_empty()).or_else(|| {
46 feed.iter().find(|(key, v)| key.starts_with("offer.") && key.rsplit('.').next() == Some(k) && !v.trim().is_empty()).map(|(_, v)| v.trim().to_string())
47 })
48 };
49 let url = get(FEED_FLEET)?;
50 let instance = get(FEED_FLEET_INSTANCE)?;
51 Some(FleetConfig { url, at: get(FEED_FLEET_AT), ca_pem: get(FEED_FLEET_CA), instance, role: String::new(), monetize_pubkey: get(FEED_MONETIZE).unwrap_or_default() })
52 }
53
54 pub fn load(root: &Path) -> std::io::Result<Option<FleetConfig>> {
56 match std::fs::read(root.join(CONFIG_REL)) {
57 Ok(b) => serde_json::from_slice(&b).map(Some).map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e)),
58 Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(None),
59 Err(e) => Err(e),
60 }
61 }
62
63 pub fn save(&self, root: &Path) -> std::io::Result<()> {
64 let bytes = serde_json::to_vec_pretty(self).map_err(std::io::Error::other)?;
65 crate::write_atomic(&root.join(CONFIG_REL), &bytes, true)
66 }
67
68 pub fn key(&self) -> Option<[u8; 32]> {
70 crate::key32(&self.monetize_pubkey)
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 #[test]
79 fn the_feed_names_the_door_the_estate_and_the_key_plain_or_offered() {
80 let k = "11".repeat(32);
81 let feed: BTreeMap<String, String> = [("offer.front.fleet", "https://monetize.ignalina.dk"), ("offer.front.fleet_instance", "acme"), ("monetize_pubkey", k.as_str())].iter().map(|(a, b)| (a.to_string(), b.to_string())).collect();
82 let c = FleetConfig::from_feed(&feed).unwrap();
83 assert_eq!((c.url.as_str(), c.instance.as_str()), ("https://monetize.ignalina.dk", "acme"));
84 assert_eq!(c.key(), Some([0x11; 32]));
85 assert_eq!(FleetConfig::from_feed(&BTreeMap::new()), None);
86 let dir = tempfile::tempdir().unwrap();
87 c.save(dir.path()).unwrap();
88 assert_eq!(FleetConfig::load(dir.path()).unwrap(), Some(c));
89 }
90}