use crate::types::OptionalInteger;
use crate::{Config, ConnMgr, Discovery, Flag, Mdns};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Profile {
Server,
LocalDiscovery,
Test,
Lowpower,
AnnounceOff,
AnnounceOn,
Randomports,
LegacyCidV0,
TestCidV1,
}
impl Profile {
pub fn from_name(name: &str) -> Option<Self> {
match name.to_lowercase().as_str() {
"server" => Some(Profile::Server),
"local-discovery" => Some(Profile::LocalDiscovery),
"test" => Some(Profile::Test),
"lowpower" => Some(Profile::Lowpower),
"announce-off" => Some(Profile::AnnounceOff),
"announce-on" => Some(Profile::AnnounceOn),
"randomports" => Some(Profile::Randomports),
"legacy-cid-v0" => Some(Profile::LegacyCidV0),
"test-cid-v1" => Some(Profile::TestCidV1),
_ => None,
}
}
pub fn name(&self) -> &'static str {
match self {
Profile::Server => "server",
Profile::LocalDiscovery => "local-discovery",
Profile::Test => "test",
Profile::Lowpower => "lowpower",
Profile::AnnounceOff => "announce-off",
Profile::AnnounceOn => "announce-on",
Profile::Randomports => "randomports",
Profile::LegacyCidV0 => "legacy-cid-v0",
Profile::TestCidV1 => "test-cid-v1",
}
}
pub fn description(&self) -> &'static str {
match self {
Profile::Server => "Recommended for nodes with public IPv4 address. Disables local discovery, enables DHT server mode.",
Profile::LocalDiscovery => "Enables local network discovery via mDNS.",
Profile::Test => "Reduces resource usage for testing. Uses in-memory datastore, disables discovery.",
Profile::Lowpower => "Reduces resource usage for low-power devices. Reduces connection limits.",
Profile::AnnounceOff => "Disables address announcement to the DHT.",
Profile::AnnounceOn => "Enables address announcement to the DHT (default).",
Profile::Randomports => "Uses random ports for swarm listening.",
Profile::LegacyCidV0 => "Uses CIDv0 by default when adding content.",
Profile::TestCidV1 => "Uses CIDv1 with raw leaves by default.",
}
}
pub fn apply(&self, config: &mut Config) {
match self {
Profile::Server => {
config.discovery = Discovery {
mdns: Mdns { enabled: false },
};
config.swarm.conn_mgr = ConnMgr {
low_water: Some(OptionalInteger(Some(100))),
high_water: Some(OptionalInteger(Some(400))),
grace_period: None,
..Default::default()
};
}
Profile::LocalDiscovery => {
config.discovery = Discovery {
mdns: Mdns { enabled: true },
};
}
Profile::Test => {
config.discovery = Discovery {
mdns: Mdns { enabled: false },
};
config.bootstrap = vec![];
config.swarm.conn_mgr = ConnMgr {
low_water: Some(OptionalInteger(Some(2))),
high_water: Some(OptionalInteger(Some(10))),
..Default::default()
};
}
Profile::Lowpower => {
config.swarm.conn_mgr = ConnMgr {
low_water: Some(OptionalInteger(Some(20))),
high_water: Some(OptionalInteger(Some(40))),
..Default::default()
};
}
Profile::AnnounceOff => {
config.addresses.no_announce = vec![
"/ip4/0.0.0.0/ipcidr/0".to_string(),
"/ip6/::/ipcidr/0".to_string(),
];
}
Profile::AnnounceOn => {
config.addresses.no_announce = vec![];
}
Profile::Randomports => {
config.addresses.swarm = vec![
"/ip4/0.0.0.0/tcp/0".to_string(),
"/ip6/::/tcp/0".to_string(),
"/ip4/0.0.0.0/udp/0/quic-v1".to_string(),
"/ip6/::/udp/0/quic-v1".to_string(),
];
}
Profile::LegacyCidV0 => {
config.import.cid_version = Some(OptionalInteger(Some(0)));
}
Profile::TestCidV1 => {
config.import.cid_version = Some(OptionalInteger(Some(1)));
config.import.unixfs_raw_leaves = Some(Flag::True);
}
}
}
}
pub fn list_profiles() -> Vec<Profile> {
vec![
Profile::Server,
Profile::LocalDiscovery,
Profile::Test,
Profile::Lowpower,
Profile::AnnounceOff,
Profile::AnnounceOn,
Profile::Randomports,
Profile::LegacyCidV0,
Profile::TestCidV1,
]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_profile_from_name() {
assert_eq!(Profile::from_name("server"), Some(Profile::Server));
assert_eq!(Profile::from_name("test"), Some(Profile::Test));
assert_eq!(Profile::from_name("unknown"), None);
}
#[test]
fn test_profile_apply_server() {
let mut config = Config::default();
Profile::Server.apply(&mut config);
assert!(!config.discovery.mdns.enabled);
}
#[test]
fn test_profile_apply_test() {
let mut config = Config::default();
Profile::Test.apply(&mut config);
assert!(config.bootstrap.is_empty());
}
#[test]
fn test_list_profiles() {
let profiles = list_profiles();
assert!(profiles.len() >= 8);
}
}