1 //! 任务日志 2 //! 3 //! DADK在执行任务时,会把一些日志记录到任务的文件夹下。 4 5 use chrono::{DateTime, Utc}; 6 use log::warn; 7 use serde::{Deserialize, Deserializer, Serialize}; 8 9 /// 任务日志(输出到任务构建日志目录下的) 10 #[derive(Debug, Clone, Serialize, Deserialize)] 11 pub struct TaskLog { 12 /// 任务执行完成时间 13 #[serde( 14 deserialize_with = "ok_or_default", 15 skip_serializing_if = "Option::is_none" 16 )] 17 build_timestamp: Option<DateTime<Utc>>, 18 install_timestamp: Option<DateTime<Utc>>, 19 /// 任务构建状态 20 build_status: Option<BuildStatus>, 21 /// 任务安装状态 22 install_status: Option<InstallStatus>, 23 } 24 25 fn ok_or_default<'a, T, D>(deserializer: D) -> Result<T, D::Error> 26 where 27 T: Deserialize<'a> + Default, 28 D: Deserializer<'a>, 29 { 30 let r = Option::deserialize(deserializer).map(|x: Option<T>| x.unwrap_or_default()); 31 32 Ok(r.unwrap_or_default()) 33 } 34 35 impl TaskLog { 36 pub fn new() -> Self { 37 Self { 38 build_timestamp: None, 39 build_status: None, 40 install_timestamp: None, 41 install_status: None, 42 } 43 } 44 45 #[allow(dead_code)] 46 pub fn set_build_time(&mut self, time: DateTime<Utc>) { 47 self.build_timestamp = Some(time); 48 } 49 50 pub fn build_time(&self) -> Option<&DateTime<Utc>> { 51 self.build_timestamp.as_ref() 52 } 53 54 pub fn set_build_time_now(&mut self) { 55 self.build_timestamp = Some(Utc::now()); 56 } 57 58 pub fn install_time(&self) -> Option<&DateTime<Utc>> { 59 self.install_timestamp.as_ref() 60 } 61 62 pub fn set_install_time_now(&mut self) { 63 self.install_timestamp = Some(Utc::now()); 64 } 65 66 pub fn set_build_status(&mut self, status: BuildStatus) { 67 self.build_status = Some(status); 68 } 69 70 pub fn clean_build_status(&mut self) { 71 self.build_status = None; 72 } 73 74 pub fn build_status(&self) -> Option<&BuildStatus> { 75 self.build_status.as_ref() 76 } 77 78 pub fn install_status(&self) -> Option<&InstallStatus> { 79 self.install_status.as_ref() 80 } 81 82 pub fn set_install_status(&mut self, status: InstallStatus) { 83 self.install_status = Some(status); 84 } 85 86 pub fn clean_install_status(&mut self) { 87 self.install_status = None; 88 } 89 } 90 91 /// 任务构建状态 92 #[derive(Debug, Clone, Serialize, PartialEq)] 93 pub enum BuildStatus { 94 #[serde(rename = "success")] 95 Success, 96 #[serde(rename = "failed")] 97 Failed, 98 } 99 100 impl<'de> Deserialize<'de> for BuildStatus { 101 fn deserialize<D>(deserializer: D) -> Result<BuildStatus, D::Error> 102 where 103 D: Deserializer<'de>, 104 { 105 let s = String::deserialize(deserializer)?.to_ascii_lowercase(); 106 match s.as_str() { 107 "success" => Ok(BuildStatus::Success), 108 "failed" => Ok(BuildStatus::Failed), 109 _ => { 110 warn!("invalid build status: {}", s); 111 Ok(BuildStatus::Failed) 112 } 113 } 114 } 115 } 116 117 /// 任务安装状态 118 #[derive(Debug, Clone, Serialize, PartialEq)] 119 pub enum InstallStatus { 120 #[serde(rename = "success")] 121 Success, 122 #[serde(rename = "failed")] 123 Failed, 124 } 125 126 impl<'de> Deserialize<'de> for InstallStatus { 127 fn deserialize<D>(deserializer: D) -> Result<InstallStatus, D::Error> 128 where 129 D: Deserializer<'de>, 130 { 131 let s = String::deserialize(deserializer)?.to_ascii_lowercase(); 132 match s.as_str() { 133 "success" => Ok(InstallStatus::Success), 134 "failed" => Ok(InstallStatus::Failed), 135 _ => { 136 warn!("invalid install status: {}", s); 137 Ok(InstallStatus::Failed) 138 } 139 } 140 } 141 } 142