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 /// 任务构建状态 19 build_status: Option<BuildStatus>, 20 /// 任务安装状态 21 install_status: Option<InstallStatus>, 22 } 23 24 fn ok_or_default<'a, T, D>(deserializer: D) -> Result<T, D::Error> 25 where 26 T: Deserialize<'a> + Default, 27 D: Deserializer<'a>, 28 { 29 let r = Option::deserialize(deserializer).map(|x: Option<T>| x.unwrap_or_default()); 30 31 Ok(r.unwrap_or_default()) 32 } 33 34 impl TaskLog { 35 pub fn new() -> Self { 36 Self { 37 build_timestamp: None, 38 build_status: None, 39 install_status: None, 40 } 41 } 42 43 #[allow(dead_code)] 44 pub fn set_build_time(&mut self, time: DateTime<Utc>) { 45 self.build_timestamp = Some(time); 46 } 47 48 #[allow(dead_code)] 49 pub fn build_time(&self) -> Option<&DateTime<Utc>> { 50 self.build_timestamp.as_ref() 51 } 52 53 #[allow(dead_code)] 54 pub fn set_build_time_now(&mut self) { 55 self.build_timestamp = Some(Utc::now()); 56 } 57 58 pub fn set_build_status(&mut self, status: BuildStatus) { 59 self.build_status = Some(status); 60 } 61 62 pub fn clean_build_status(&mut self) { 63 self.build_status = None; 64 } 65 66 pub fn build_status(&self) -> Option<&BuildStatus> { 67 self.build_status.as_ref() 68 } 69 70 pub fn install_status(&self) -> Option<&InstallStatus> { 71 self.install_status.as_ref() 72 } 73 74 pub fn set_install_status(&mut self, status: InstallStatus) { 75 self.install_status = Some(status); 76 } 77 78 pub fn clean_install_status(&mut self) { 79 self.install_status = None; 80 } 81 } 82 83 /// 任务构建状态 84 #[derive(Debug, Clone, Serialize, PartialEq)] 85 pub enum BuildStatus { 86 #[serde(rename = "success")] 87 Success, 88 #[serde(rename = "failed")] 89 Failed, 90 } 91 92 impl<'de> Deserialize<'de> for BuildStatus { 93 fn deserialize<D>(deserializer: D) -> Result<BuildStatus, D::Error> 94 where 95 D: Deserializer<'de>, 96 { 97 let s = String::deserialize(deserializer)?.to_ascii_lowercase(); 98 match s.as_str() { 99 "success" => Ok(BuildStatus::Success), 100 "failed" => Ok(BuildStatus::Failed), 101 _ => { 102 warn!("invalid build status: {}", s); 103 Ok(BuildStatus::Failed) 104 } 105 } 106 } 107 } 108 109 /// 任务安装状态 110 #[derive(Debug, Clone, Serialize, PartialEq)] 111 pub enum InstallStatus { 112 #[serde(rename = "success")] 113 Success, 114 #[serde(rename = "failed")] 115 Failed, 116 } 117 118 impl<'de> Deserialize<'de> for InstallStatus { 119 fn deserialize<D>(deserializer: D) -> Result<InstallStatus, D::Error> 120 where 121 D: Deserializer<'de>, 122 { 123 let s = String::deserialize(deserializer)?.to_ascii_lowercase(); 124 match s.as_str() { 125 "success" => Ok(InstallStatus::Success), 126 "failed" => Ok(InstallStatus::Failed), 127 _ => { 128 warn!("invalid install status: {}", s); 129 Ok(InstallStatus::Failed) 130 } 131 } 132 } 133 } 134