use core::str;
use serde::Serialize;
use crate::{
command::{Command, CommandLevel},
error::Result,
};
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct StaticNetConfig {
pub ip: String,
pub netmask: String,
pub gateway: String,
pub dns: String,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum NetConfigParam {
Dhcp,
Static(StaticNetConfig),
}
impl serde::Serialize for NetConfigParam {
fn serialize<S: serde::Serializer>(
&self,
serializer: S,
) -> std::result::Result<S::Ok, S::Error> {
match self {
Self::Dhcp => "dhcp".serialize(serializer),
Self::Static(config) => config.serialize(serializer),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SetSystemNetConfig {
pub config: NetConfigParam,
}
impl SetSystemNetConfig {
pub fn new(config: NetConfigParam) -> Self {
Self { config }
}
pub fn dhcp() -> Self {
Self {
config: NetConfigParam::Dhcp,
}
}
pub fn static_ip(config: StaticNetConfig) -> Self {
Self {
config: NetConfigParam::Static(config),
}
}
}
impl Command for SetSystemNetConfig {
type Response = String;
const CMD_NAME: &'static str = "set.system.net_config";
const LEVEL: CommandLevel = CommandLevel::Secured;
fn params(&self) -> Result<Option<impl serde::Serialize>> {
Ok(Some(&self.config))
}
}
#[cfg(test)]
mod tests {
use crate::account::Account;
use crate::auth_data::AuthData;
use super::*;
const RESPONSE_JSON: &str =
r#"{"code":0,"when":1672281726,"msg":"ok","desc":"set.system.net_config"}"#;
#[test]
fn request_dhcp_mode() {
let cmd = SetSystemNetConfig::dhcp();
assert!(cmd.is_secured());
assert!(!cmd.is_encrypted());
let auth = AuthData::new::<SetSystemNetConfig>(Account::Super, "pass", "salt").unwrap();
let encoded = cmd.encode(Some(auth)).unwrap();
let json: serde_json::Value = serde_json::from_slice(&encoded.0).unwrap();
assert_eq!(json["cmd"], "set.system.net_config");
assert_eq!(json["param"], "dhcp");
assert_eq!(json["account"], "super");
assert!(json["ts"].as_u64().unwrap() > 0);
assert_eq!(json["token"].as_str().unwrap().len(), 8);
}
#[test]
fn request_static_mode() {
let cmd = SetSystemNetConfig::static_ip(StaticNetConfig {
ip: "192.168.2.22".to_string(),
netmask: "255.255.255.0".to_string(),
gateway: "192.168.2.1".to_string(),
dns: "192.168.2.1".to_string(),
});
let auth = AuthData::new::<SetSystemNetConfig>(Account::Super, "pass", "salt").unwrap();
let encoded = cmd.encode(Some(auth)).unwrap();
let json: serde_json::Value = serde_json::from_slice(&encoded.0).unwrap();
assert_eq!(json["cmd"], "set.system.net_config");
assert_eq!(json["param"]["ip"], "192.168.2.22");
}
#[test]
fn request_without_auth_omits_token() {
let cmd = SetSystemNetConfig::dhcp();
let encoded = cmd.encode(None).unwrap();
let json: serde_json::Value = serde_json::from_slice(&encoded.0).unwrap();
assert!(json.get("token").is_none());
assert_eq!(json["param"], "dhcp");
}
#[test]
fn deserialize_response_fixture() {
let response = SetSystemNetConfig::parse_response(RESPONSE_JSON.as_bytes()).unwrap();
assert!(response.code.is_success());
assert_eq!(response.desc, "set.system.net_config");
assert_eq!(response.when, 1672281726);
assert_eq!(response.msg, "ok");
}
}