use crate::entity::ip_detail::IpDetail;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct IpInfo {
pub create_ip: Option<String>,
pub create_ip_detail: Option<IpDetail>,
pub update_ip: Option<String>,
pub update_ip_detail: Option<IpDetail>,
}
impl IpInfo {
pub fn new() -> Self {
Self::default()
}
pub fn refresh_ip(&mut self, ip: Option<String>) {
let ip = match ip {
Some(ip) if !ip.trim().is_empty() => ip,
_ => return,
};
self.update_ip = Some(ip.clone());
if self.create_ip.is_none() {
self.create_ip = Some(ip);
}
}
pub fn need_refresh_ip(&self) -> Option<&String> {
let not_need_refresh = self
.update_ip_detail
.as_ref()
.and_then(|detail| detail.ip.as_ref())
.map(|ip| ip == self.update_ip.as_ref().unwrap_or(&String::new()))
.unwrap_or(false);
if not_need_refresh {
None
} else {
self.update_ip.as_ref()
}
}
pub fn refresh_ip_detail(&mut self, ip_detail: IpDetail) {
if let Some(ip) = &ip_detail.ip {
if self.create_ip.as_ref().map(|s| s == ip).unwrap_or(false) {
self.create_ip_detail = Some(ip_detail.clone());
}
if self.update_ip.as_ref().map(|s| s == ip).unwrap_or(false) {
self.update_ip_detail = Some(ip_detail);
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_refresh_ip() {
let mut ip_info = IpInfo::new();
ip_info.refresh_ip(Some("127.0.0.1".to_string()));
assert_eq!(ip_info.create_ip, Some("127.0.0.1".to_string()));
assert_eq!(ip_info.update_ip, Some("127.0.0.1".to_string()));
ip_info.refresh_ip(Some("192.168.1.1".to_string()));
assert_eq!(ip_info.create_ip, Some("127.0.0.1".to_string())); assert_eq!(ip_info.update_ip, Some("192.168.1.1".to_string()));
ip_info.refresh_ip(Some("".to_string()));
assert_eq!(ip_info.update_ip, Some("192.168.1.1".to_string()));
ip_info.refresh_ip(None);
assert_eq!(ip_info.update_ip, Some("192.168.1.1".to_string())); }
#[test]
fn test_need_refresh_ip() {
let mut ip_info = IpInfo::new();
assert_eq!(ip_info.need_refresh_ip(), None);
ip_info.update_ip = Some("127.0.0.1".to_string());
assert_eq!(ip_info.need_refresh_ip(), Some(&"127.0.0.1".to_string()));
ip_info.update_ip_detail = Some(IpDetail::builder().ip("192.168.1.1".to_string()).build());
assert_eq!(ip_info.need_refresh_ip(), Some(&"127.0.0.1".to_string()));
ip_info.update_ip_detail = Some(IpDetail::builder().ip("127.0.0.1".to_string()).build());
assert_eq!(ip_info.need_refresh_ip(), None);
}
#[test]
fn test_refresh_ip_detail() {
let mut ip_info = IpInfo::new();
ip_info.create_ip = Some("127.0.0.1".to_string());
ip_info.update_ip = Some("192.168.1.1".to_string());
let create_detail = IpDetail::builder()
.ip("127.0.0.1".to_string())
.city("北京".to_string())
.build();
ip_info.refresh_ip_detail(create_detail.clone());
assert_eq!(ip_info.create_ip_detail, Some(create_detail));
assert_eq!(ip_info.update_ip_detail, None);
let update_detail = IpDetail::builder()
.ip("192.168.1.1".to_string())
.city("上海".to_string())
.build();
ip_info.refresh_ip_detail(update_detail.clone());
assert_eq!(ip_info.update_ip_detail, Some(update_detail));
let other_detail = IpDetail::builder()
.ip("10.0.0.1".to_string())
.city("广州".to_string())
.build();
let create_detail_before = ip_info.create_ip_detail.clone();
let update_detail_before = ip_info.update_ip_detail.clone();
ip_info.refresh_ip_detail(other_detail);
assert_eq!(ip_info.create_ip_detail, create_detail_before);
assert_eq!(ip_info.update_ip_detail, update_detail_before);
}
#[test]
fn test_deserialize_from_json() {
let json_str = r#"{
"createIp": "206.237.119.215",
"updateIp": "120.231.232.41",
"createIpDetail": {
"ip": "206.237.119.215",
"isp": "",
"area": "",
"city": "",
"ispId": "",
"region": "",
"cityId": "",
"country": "美国",
"regionId": "",
"countryId": "US"
},
"updateIpDetail": {
"ip": "120.231.232.41",
"isp": "移动",
"area": "",
"city": "",
"ispId": "100025",
"region": "广东",
"cityId": "",
"country": "中国",
"regionId": "440000",
"countryId": "CN"
}
}"#;
let ip_info: IpInfo = serde_json::from_str(json_str).expect("反序列化 JSON 失败");
assert_eq!(ip_info.create_ip, Some("206.237.119.215".to_string()));
assert_eq!(ip_info.update_ip, Some("120.231.232.41".to_string()));
assert!(ip_info.create_ip_detail.is_some());
let create_detail = ip_info.create_ip_detail.as_ref().unwrap();
assert_eq!(create_detail.ip, Some("206.237.119.215".to_string()));
assert_eq!(create_detail.country, Some("美国".to_string()));
assert_eq!(create_detail.country_id, Some("US".to_string()));
assert_eq!(create_detail.isp, Some("".to_string()));
assert_eq!(create_detail.area, Some("".to_string()));
assert!(ip_info.update_ip_detail.is_some());
let update_detail = ip_info.update_ip_detail.as_ref().unwrap();
assert_eq!(update_detail.ip, Some("120.231.232.41".to_string()));
assert_eq!(update_detail.isp, Some("移动".to_string()));
assert_eq!(update_detail.isp_id, Some("100025".to_string()));
assert_eq!(update_detail.region, Some("广东".to_string()));
assert_eq!(update_detail.region_id, Some("440000".to_string()));
assert_eq!(update_detail.country, Some("中国".to_string()));
assert_eq!(update_detail.country_id, Some("CN".to_string()));
}
#[test]
fn test_serialize_to_json() {
let mut ip_info = IpInfo::new();
ip_info.create_ip = Some("206.237.119.215".to_string());
ip_info.update_ip = Some("120.231.232.41".to_string());
let create_detail = IpDetail::builder()
.ip("206.237.119.215".to_string())
.country("美国".to_string())
.country_id("US".to_string())
.isp("".to_string())
.area("".to_string())
.build();
ip_info.create_ip_detail = Some(create_detail);
let update_detail = IpDetail::builder()
.ip("120.231.232.41".to_string())
.isp("移动".to_string())
.isp_id("100025".to_string())
.region("广东".to_string())
.region_id("440000".to_string())
.country("中国".to_string())
.country_id("CN".to_string())
.build();
ip_info.update_ip_detail = Some(update_detail);
let json_str = serde_json::to_string(&ip_info).expect("序列化 JSON 失败");
let deserialized: IpInfo = serde_json::from_str(&json_str).expect("反序列化 JSON 失败");
assert_eq!(deserialized.create_ip, ip_info.create_ip);
assert_eq!(deserialized.update_ip, ip_info.update_ip);
assert_eq!(deserialized.create_ip_detail, ip_info.create_ip_detail);
assert_eq!(deserialized.update_ip_detail, ip_info.update_ip_detail);
}
}