Skip to content

Commit

Permalink
Add object copy by serde.
Browse files Browse the repository at this point in the history
  • Loading branch information
gudaoxuri committed Sep 20, 2022
1 parent f6f18c2 commit 33eb115
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 0 deletions.
2 changes: 2 additions & 0 deletions tardis/res/locale/zh-cn.tardis
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
406-tardis-json-str-to-json-error Json字符串转Json错误
406-tardis-json-obj-to-str-error 对象转Json字符串错误
406-tardis-json-json-to-str-error Json转Json字符串错误
406-tardis-json-copy-serialize-error 对象复制序列化错误
406-tardis-json-copy-deserialize-error 对象复制反序列化错误

406-tardis-crypto-aes-key-invalid AES Key格式错误
406-tardis-crypto-aes-error AES处理错误
Expand Down
14 changes: 14 additions & 0 deletions tardis/src/basic/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,18 @@ impl TardisJson {
Err(err) => Err(TardisError::format_error(&format!("[Tardis.Json] {:?}", err), "406-tardis-json-json-to-str-error")),
}
}

pub fn copy<F: Serialize, T: DeserializeOwned>(&self, source: &F) -> TardisResult<T> {
let result = serde_json::to_value(source);
match result {
Ok(value) => {
let result = serde_json::from_value::<T>(value);
match result {
Ok(r) => Ok(r),
Err(err) => Err(TardisError::format_error(&format!("[Tardis.Json] {:?}", err), "406-tardis-json-copy-deserialize-error")),
}
}
Err(err) => Err(TardisError::format_error(&format!("[Tardis.Json] {:?}", err), "406-tardis-json-copy-serialize-error")),
}
}
}
109 changes: 109 additions & 0 deletions tardis/tests/test_basic_json.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use chrono::{DateTime, TimeZone, Utc};
use serde::Deserializer;
use tardis::basic::dto::TardisContext;
use tardis::basic::field::TrimString;
use tardis::basic::result::TardisResult;
use tardis::serde::{Deserialize, Serialize};
use tardis::TardisFuns;
Expand Down Expand Up @@ -49,6 +52,43 @@ async fn test_basic_json() -> TardisResult<()> {
let ctx = TardisFuns::json.obj_to_string(&ctx)?;
assert_eq!(ctx, r#"{"own_paths":"ss/","ak":"","owner":"","roles":[],"groups":[]}"#);

let req_dto = UserAddReq {
name: TrimString("星航大大".to_lowercase()),
pwd: "123456".to_string(),
age: 10,
roles: vec![
UserRoleReq {
code: TrimString("admin".to_lowercase()),
name: "管理员".to_string(),
},
UserRoleReq {
code: TrimString("user".to_lowercase()),
name: "用户".to_string(),
},
],
org: Some(UserOrgReq {
code: TrimString("org1".to_lowercase()),
name: "组织1".to_string(),
}),
status: Some(true),
front_field: "front_field".to_string(),
};

let user_info: UserInfo = TardisFuns::json.copy(&req_dto)?;
assert_eq!(user_info.id, "idxx");
assert_eq!(user_info.name, "星航大大");
assert_eq!(user_info.password, "123456");
assert_eq!(user_info.age, 10);
assert_eq!(user_info.roles.len(), 2);
assert_eq!(user_info.roles[0].code, "admin");
assert_eq!(user_info.roles[0].name, "管理员");
assert_eq!(user_info.roles[1].code, "user");
assert_eq!(user_info.roles[1].name, "用户");
assert_eq!(user_info.org.as_ref().unwrap().code, "org1");
assert_eq!(user_info.org.as_ref().unwrap().name, "组织1");
assert_eq!(user_info.status, true);
assert!(user_info.create_time.timestamp() <= Utc::now().timestamp());

Ok(())
}

Expand Down Expand Up @@ -81,3 +121,72 @@ impl Default for DatabaseConfig {
DatabaseConfig { url: "".to_string() }
}
}

#[derive(Serialize, Deserialize)]
struct UserAddReq {
pub name: TrimString,
#[serde(rename(serialize = "password"))]
pub pwd: String,
pub age: u8,
pub roles: Vec<UserRoleReq>,
pub org: Option<UserOrgReq>,
pub status: Option<bool>,
// no need to copy
pub front_field: String,
}

#[derive(Serialize, Deserialize)]
struct UserRoleReq {
pub code: TrimString,
pub name: String,
}

#[derive(Serialize, Deserialize)]
struct UserOrgReq {
pub code: TrimString,
pub name: String,
}

#[derive(Serialize, Deserialize)]
struct UserInfo {
#[serde(default = "id_default")]
pub id: String,
pub name: String,
pub password: String,
pub age: u8,
pub roles: Vec<UserRoleInfo>,
pub org: Option<UserOrgInfo>,
pub status: bool,
#[serde(default = "create_time_default")]
#[serde(skip_serializing)]
#[serde(deserialize_with = "deserialize_time")]
pub create_time: DateTime<Utc>,
}

fn id_default() -> String {
"idxx".to_string()
}

fn create_time_default() -> DateTime<Utc> {
Utc::now()
}

pub fn deserialize_time<'de, D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Utc.datetime_from_str(&s, "%Y-%m-%d %H:%M:%S").map_err(serde::de::Error::custom)
}

#[derive(Serialize, Deserialize)]
struct UserRoleInfo {
pub code: String,
pub name: String,
}

#[derive(Serialize, Deserialize)]
struct UserOrgInfo {
pub code: String,
pub name: String,
}

0 comments on commit 33eb115

Please sign in to comment.