From 757139d32622c28fa5eae1c2630507f3147b9f4d Mon Sep 17 00:00:00 2001 From: xuxiaozhou1 Date: Tue, 19 Mar 2024 12:46:11 +0800 Subject: [PATCH] fix: adjust the range and order of setting temporary properties for units --- core/coms/path/src/bus.rs | 70 +++++--------------------- core/coms/path/src/rentry.rs | 11 ++-- core/coms/service/src/bus.rs | 8 +-- core/coms/service/src/rentry.rs | 51 ++++++++++--------- core/coms/socket/src/bus.rs | 5 +- core/coms/socket/src/rentry.rs | 31 ++++-------- core/coms/timer/src/bus.rs | 58 +++------------------ core/coms/timer/src/rentry.rs | 4 +- core/sysmaster/src/unit/bus.rs | 2 + core/sysmaster/src/unit/rentry.rs | 84 ++++++++++++++++++------------- 10 files changed, 121 insertions(+), 203 deletions(-) diff --git a/core/coms/path/src/bus.rs b/core/coms/path/src/bus.rs index 12d0fbf3..7bcac288 100644 --- a/core/coms/path/src/bus.rs +++ b/core/coms/path/src/bus.rs @@ -37,23 +37,14 @@ impl PathBus { value: &str, flags: UnitWriteFlags, ) -> Result<()> { - let mut ret = self.cgroup_set_transient_property(key, value, flags); - if let Err(Error::NotFound { what: _ }) = ret { - let unit = self.comm.owner().unwrap(); - if unit.transient() && unit.is_load_stub() { - ret = self.unit_set_transient_property(key, value, flags); - - if let Err(Error::NotFound { what: _ }) = ret { - ret = self.exec_set_transient_property(key, value, flags); - } - - if let Err(Error::NotFound { what: _ }) = ret { - ret = self.kill_set_transient_property(key, value, flags); - } - } + let unit = self.comm.owner().unwrap(); + if unit.transient() && unit.is_load_stub() { + return self.unit_set_transient_property(key, value, flags); } - ret + Err(Error::NotFound { + what: format!("set property:{}", key), + }) } fn unit_set_transient_property( @@ -64,55 +55,18 @@ impl PathBus { ) -> Result<()> { let real_flags = flags | UnitWriteFlags::PRIVATE; match key { - "Unit" - | "MakeDirectory" - | "DirectoryMode" - | "TriggerLimitBurst" - | "TriggerLimitIntervalSec" => self.unit_write_property(key, value, real_flags, false), - "PathExists" | "PathExistsGlob" | "PathChanged" | "PathModified" - | "DirectoryNotEmpty" => self.unit_write_property(key, value, real_flags, false), + "MakeDirectory" | "DirectoryMode" | "TriggerLimitBurst" | "TriggerLimitIntervalSec" => { + self.unit_write_property(key, value, real_flags, false) + } + "PathExists" | "PathExistsGlob" | "PathChanged" | "PathModified" => { + self.unit_write_property(key, value, real_flags, false) + } str_key => Err(Error::NotFound { what: format!("set transient property:{}", str_key), }), } } - fn exec_set_transient_property( - &self, - key: &str, - _value: &str, - _flags: UnitWriteFlags, - ) -> Result<()> { - // not supported now - Err(Error::NotFound { - what: format!("set exec property:{}", key), - }) - } - - fn kill_set_transient_property( - &self, - key: &str, - _value: &str, - _flags: UnitWriteFlags, - ) -> Result<()> { - // not supported now - Err(Error::NotFound { - what: format!("set kill property:{}", key), - }) - } - - fn cgroup_set_transient_property( - &self, - key: &str, - _value: &str, - _flags: UnitWriteFlags, - ) -> Result<()> { - // not supported now - Err(Error::NotFound { - what: format!("set cgroup property:{}", key), - }) - } - fn unit_write_property( &self, key: &str, diff --git a/core/coms/path/src/rentry.rs b/core/coms/path/src/rentry.rs index 794ae130..e2b16695 100644 --- a/core/coms/path/src/rentry.rs +++ b/core/coms/path/src/rentry.rs @@ -72,17 +72,16 @@ impl SectionPath { value: &str, ) -> Result<(), core::error::Error> { match key { - "Unit" => self.Unit = value.to_string(), - "MakeDirectory" => self.MakeDirectory = parse_boolean(value)?, - "DirectoryMode" => self.DirectoryMode = parse_mode(value)?, - "TriggerLimitBurst" => self.TriggerLimitBurst = value.parse::()?, - "TriggerLimitIntervalSec" => self.TriggerLimitIntervalSec = value.parse::()?, - //Paths "PathExists" => self.PathExists = parse_pathbuf_vec(value)?, "PathExistsGlob" => self.PathExistsGlob = parse_pathbuf_vec(value)?, "PathChanged" => self.PathChanged = parse_pathbuf_vec(value)?, "PathModified" => self.PathModified = parse_pathbuf_vec(value)?, "DirectoryNotEmpty" => self.DirectoryNotEmpty = parse_pathbuf_vec(value)?, + "Unit" => self.Unit = value.to_string(), + "MakeDirectory" => self.MakeDirectory = parse_boolean(value)?, + "DirectoryMode" => self.DirectoryMode = parse_mode(value)?, + "TriggerLimitBurst" => self.TriggerLimitBurst = value.parse::()?, + "TriggerLimitIntervalSec" => self.TriggerLimitIntervalSec = value.parse::()?, str_key => { return Err(Error::NotFound { what: format!("set timer property:{}", str_key), diff --git a/core/coms/service/src/bus.rs b/core/coms/service/src/bus.rs index c96997b2..d16ebe06 100644 --- a/core/coms/service/src/bus.rs +++ b/core/coms/service/src/bus.rs @@ -66,6 +66,10 @@ impl ServiceBus { match key { "RemainAfterExit" | "Type" + | "RestartSec" + | "TimeoutStartSec" + | "TimeoutStopSec" + | "WatchdogSec" | "NotifyAccess" | "PIDFile" | "Restart" @@ -99,9 +103,7 @@ impl ServiceBus { | "Environment" | "EnvironmentFile" | "RuntimeDirectory" - | "StateDirectory" - | "ExecReload" - | "ExecCondition" => self.unit_write_property(key, value, real_flags, false), + | "StateDirectory" => self.unit_write_property(key, value, real_flags, false), "LimitCORE" | "LimitNOFILE" | "LimitNPROC" => { self.unit_write_property(key, value, real_flags, false) } diff --git a/core/coms/service/src/rentry.rs b/core/coms/service/src/rentry.rs index 8022e20d..b6575228 100644 --- a/core/coms/service/src/rentry.rs +++ b/core/coms/service/src/rentry.rs @@ -338,18 +338,7 @@ impl SectionService { pub(super) fn set_property(&mut self, key: &str, value: &str) -> Result<()> { match key { - "RemainAfterExit" => self.RemainAfterExit = basic::config::parse_boolean(value)?, "Type" => self.Type = ServiceType::parse_from_str(value)?, - "RestartSec" => self.RestartSec = value.parse::()?, - "TimeoutSec" => self.TimeoutSec = parse_timeout(value)?, - "TimeoutStartSec" => self.TimeoutStartSec = parse_timeout(value)?, - "TimeoutStopSec" => self.TimeoutStopSec = parse_timeout(value)?, - "NotifyAccess" => self.NotifyAccess = Some(NotifyAccess::parse_from_str(value)?), - "PIDFile" => self.PIDFile = Some(parse_pidfile(value)?), - "Restart" => self.Restart = ServiceRestart::parse_from_str(value)?, - "RestartPreventExitStatus" => { - self.RestartPreventExitStatus = ExitStatusSet::parse_from_str(value)? - } "ExecStart" => self.ExecStart = core::exec::parse_exec_command(value)?, "ExecStartPre" => self.ExecStartPre = core::exec::parse_exec_command(value)?, "ExecStartPost" => self.ExecStartPost = core::exec::parse_exec_command(value)?, @@ -357,33 +346,45 @@ impl SectionService { "ExecStopPost" => self.ExecStopPost = core::exec::parse_exec_command(value)?, "ExecReload" => self.ExecReload = core::exec::parse_exec_command(value)?, "ExecCondition" => self.ExecCondition = core::exec::parse_exec_command(value)?, + "Sockets" => self.Sockets = value.split_whitespace().map(|s| s.to_string()).collect(), + "WatchdogSec" => self.WatchdogSec = value.parse::()?, + "PIDFile" => self.PIDFile = Some(parse_pidfile(value)?), + "RemainAfterExit" => self.RemainAfterExit = basic::config::parse_boolean(value)?, + "NotifyAccess" => self.NotifyAccess = Some(NotifyAccess::parse_from_str(value)?), + "NonBlocking" => self.NonBlocking = basic::config::parse_boolean(value)?, + "Restart" => self.Restart = ServiceRestart::parse_from_str(value)?, + "RestartPreventExitStatus" => { + self.RestartPreventExitStatus = ExitStatusSet::parse_from_str(value)? + } + "RestartSec" => self.RestartSec = value.parse::()?, + "TimeoutSec" => self.TimeoutSec = parse_timeout(value)?, + "TimeoutStartSec" => self.TimeoutStartSec = parse_timeout(value)?, + "TimeoutStopSec" => self.TimeoutStopSec = parse_timeout(value)?, + //exec context "User" => self.User = value.to_string(), "Group" => self.User = value.to_string(), - "RootDirectory" => self.RootDirectory = Some(parse_pathbuf(value)?), - "NonBlocking" => self.NonBlocking = basic::config::parse_boolean(value)?, - "RuntimeDirectoryPreserve" => { - self.RuntimeDirectoryPreserve = PreserveMode::parse_from_str(value)? - } "UMask" => self.UMask = value.to_string(), - "SELinuxContext" => self.SELinuxContext = Some(value.to_string()), + "RootDirectory" => self.RootDirectory = Some(parse_pathbuf(value)?), "WorkingDirectory" => { self.WorkingDirectory = core::exec::parse_working_directory(value)? } - "Environment" => self.Environment = Some(core::exec::parse_environment(value)?), - "EnvironmentFile" => { - self.EnvironmentFile = value - .split_whitespace() - .map(|str| str.to_string()) - .collect() - } + "StateDirectory" => self.StateDirectory = core::exec::parse_state_directory(value)?, "RuntimeDirectory" => { self.RuntimeDirectory = core::exec::parse_runtime_directory(value)? } - "StateDirectory" => self.StateDirectory = core::exec::parse_state_directory(value)?, + "RuntimeDirectoryPreserve" => { + self.RuntimeDirectoryPreserve = PreserveMode::parse_from_str(value)? + } "LimitCORE" => self.LimitCORE = Some(Rlimit::parse_from_str(value)?), "LimitNOFILE" => self.LimitNOFILE = Some(Rlimit::parse_from_str(value)?), "LimitNPROC" => self.LimitNPROC = Some(Rlimit::parse_from_str(value)?), + "Environment" => self.Environment = Some(core::exec::parse_environment(value)?), + "EnvironmentFile" => { + self.EnvironmentFile = value.split_whitespace().map(|s| s.to_string()).collect() + } + "SELinuxContext" => self.SELinuxContext = Some(value.to_string()), + //kill context "KillMode" => self.KillMode = KillMode::parse_from_str(value)?, "KillSignal" => self.KillSignal = value.to_string(), diff --git a/core/coms/socket/src/bus.rs b/core/coms/socket/src/bus.rs index ac98c396..fd020556 100644 --- a/core/coms/socket/src/bus.rs +++ b/core/coms/socket/src/bus.rs @@ -87,9 +87,8 @@ impl SocketBus { | "ListenSequentialPacket" | "ListenFIFO" | "ListenSpecial" => self.unit_write_property(key, value, real_flags, false), - "ExecStartPre" | "ExecStartPost" | "ExecStopPre" | "ExecStopPost" => { - self.unit_write_property(key, value, real_flags, false) - } + "ExecStartPre" | "ExecStartChown" | "ExecStartPost" | "ExecStopPre" + | "ExecStopPost" => self.unit_write_property(key, value, real_flags, false), str_key => Err(Error::NotFound { what: format!("set transient property:{}", str_key), }), diff --git a/core/coms/socket/src/rentry.rs b/core/coms/socket/src/rentry.rs index b5912246..01f60fe0 100644 --- a/core/coms/socket/src/rentry.rs +++ b/core/coms/socket/src/rentry.rs @@ -114,42 +114,32 @@ impl SectionSocket { ) -> Result<(), core::error::Error> { match key { "ExecStartPre" => self.ExecStartPre = core::exec::parse_exec_command(value)?, + "ExecStartChown" => self.ExecStartChown = core::exec::parse_exec_command(value)?, "ExecStartPost" => self.ExecStartPost = core::exec::parse_exec_command(value)?, "ExecStopPre" => self.ExecStopPre = core::exec::parse_exec_command(value)?, "ExecStopPost" => self.ExecStopPost = core::exec::parse_exec_command(value)?, + "ListenStream" => { - self.ListenStream = value - .split_whitespace() - .map(|str| str.to_string()) - .collect() + self.ListenStream = value.split_whitespace().map(|s| s.to_string()).collect() } "ListenDatagram" => { - self.ListenDatagram = value - .split_whitespace() - .map(|str| str.to_string()) - .collect() + self.ListenDatagram = value.split_whitespace().map(|s| s.to_string()).collect() } "ListenNetlink" => self.ListenNetlink = deserialize_netlink_vec(value)?, "ListenSequentialPacket" => { - self.ListenSequentialPacket = value - .split_whitespace() - .map(|str| str.to_string()) - .collect() + self.ListenSequentialPacket = + value.split_whitespace().map(|s| s.to_string()).collect() } "ListenFIFO" => { - self.ListenFIFO = value - .split_whitespace() - .map(|str| str.to_string()) - .collect() + self.ListenFIFO = value.split_whitespace().map(|s| s.to_string()).collect() } "ListenSpecial" => { - self.ListenSpecial = value - .split_whitespace() - .map(|str| str.to_string()) - .collect() + self.ListenSpecial = value.split_whitespace().map(|s| s.to_string()).collect() } + "Accept" => self.Accept = basic::config::parse_boolean(value)?, "FlushPending" => self.FlushPending = basic::config::parse_boolean(value)?, + "Service" => self.Service = Some(value.to_string()), "ReceiveBuffer" => self.ReceiveBuffer = Some(value.parse::()?), "SendBuffer" => self.SendBuffer = Some(value.parse::()?), "PassCredentials" => self.PassCredentials = Some(basic::config::parse_boolean(value)?), @@ -165,6 +155,7 @@ impl SectionSocket { "SocketMode" => self.SocketMode = parse_mode(value)?, "SocketUser" => self.SocketUser = value.to_string(), "SocketGroup" => self.SocketGroup = value.to_string(), + //kill context "KillMode" => self.KillMode = KillMode::parse_from_str(value)?, "KillSignal" => self.KillSignal = value.to_string(), diff --git a/core/coms/timer/src/bus.rs b/core/coms/timer/src/bus.rs index 6528d093..cd9cc171 100644 --- a/core/coms/timer/src/bus.rs +++ b/core/coms/timer/src/bus.rs @@ -37,23 +37,14 @@ impl TimerBus { value: &str, flags: UnitWriteFlags, ) -> Result<()> { - let mut ret = self.cgroup_set_transient_property(key, value, flags); - if let Err(Error::NotFound { what: _ }) = ret { - let unit = self.comm.owner().unwrap(); - if unit.transient() && unit.is_load_stub() { - ret = self.unit_set_transient_property(key, value, flags); - - if let Err(Error::NotFound { what: _ }) = ret { - ret = self.exec_set_transient_property(key, value, flags); - } - - if let Err(Error::NotFound { what: _ }) = ret { - ret = self.kill_set_transient_property(key, value, flags); - } - } + let unit = self.comm.owner().unwrap(); + if unit.transient() && unit.is_load_stub() { + return self.unit_set_transient_property(key, value, flags); } - ret + Err(Error::NotFound { + what: format!("set property:{}", key), + }) } fn unit_set_transient_property( @@ -69,49 +60,12 @@ impl TimerBus { | "OnUnitActiveSec" | "OnUnitInactiveSec" | "OnCalendar" => { self.unit_write_property(key, value, real_flags, false) } - "Unit" => self.unit_write_property(key, value, real_flags, false), str_key => Err(Error::NotFound { what: format!("set transient property:{}", str_key), }), } } - fn exec_set_transient_property( - &self, - key: &str, - _value: &str, - _flags: UnitWriteFlags, - ) -> Result<()> { - // not supported now - Err(Error::NotFound { - what: format!("set exec property:{}", key), - }) - } - - fn kill_set_transient_property( - &self, - key: &str, - _value: &str, - _flags: UnitWriteFlags, - ) -> Result<()> { - // not supported now - Err(Error::NotFound { - what: format!("set kill property:{}", key), - }) - } - - fn cgroup_set_transient_property( - &self, - key: &str, - _value: &str, - _flags: UnitWriteFlags, - ) -> Result<()> { - // not supported now - Err(Error::NotFound { - what: format!("set cgroup property:{}", key), - }) - } - fn unit_write_property( &self, key: &str, diff --git a/core/coms/timer/src/rentry.rs b/core/coms/timer/src/rentry.rs index 4dce7e24..9509a757 100644 --- a/core/coms/timer/src/rentry.rs +++ b/core/coms/timer/src/rentry.rs @@ -111,13 +111,13 @@ impl SectionTimer { ) -> Result<(), core::error::Error> { match key { "AccuracySec" => self.AccuracySec = parse_timer(value)?, - "RandomizedDelaySec" => self.RandomizedDelaySec = parse_timer(value)?, "OnActiveSec" => self.OnActiveSec = parse_timer(value)?, "OnBootSec" => self.OnBootSec = parse_timer(value)?, "OnStartupSec" => self.OnStartupSec = parse_timer(value)?, "OnUnitActiveSec" => self.OnUnitActiveSec = parse_timer(value)?, "OnUnitInactiveSec" => self.OnUnitInactiveSec = parse_timer(value)?, "OnCalendar" => self.OnCalendar = parse_timer(value)?, + "RandomizedDelaySec" => self.RandomizedDelaySec = parse_timer(value)?, "Unit" => { self.Unit = if value.is_empty() { None @@ -125,8 +125,8 @@ impl SectionTimer { Some(value.to_string()) } } - "WakeSystem" => self.WakeSystem = basic::config::parse_boolean(value)?, "Persistent" => self.Persistent = basic::config::parse_boolean(value)?, + "WakeSystem" => self.WakeSystem = basic::config::parse_boolean(value)?, "RemainAfterElapse" => self.RemainAfterElapse = basic::config::parse_boolean(value)?, str_key => { return Err(Error::NotFound { diff --git a/core/sysmaster/src/unit/bus.rs b/core/sysmaster/src/unit/bus.rs index b08f180b..3ea6cbd5 100644 --- a/core/sysmaster/src/unit/bus.rs +++ b/core/sysmaster/src/unit/bus.rs @@ -169,7 +169,9 @@ impl UnitBus { | "OnSuccessJobMode" | "OnFailureJobMode" | "IgnoreOnIsolate" + | "JobTimeoutSec" | "JobTimeoutAction" + | "StartLimitIntervalSec" | "StartLimitBurst" | "StartLimitAction" | "FailureAction" diff --git a/core/sysmaster/src/unit/rentry.rs b/core/sysmaster/src/unit/rentry.rs index ee888f09..e0a028ee 100644 --- a/core/sysmaster/src/unit/rentry.rs +++ b/core/sysmaster/src/unit/rentry.rs @@ -251,23 +251,28 @@ pub(crate) struct UeConfigUnit { impl UeConfigUnit { pub(crate) fn set_property(&mut self, key: &str, value: &str) -> Result<()> { match key { - "RefuseManualStart" => self.RefuseManualStart = basic::config::parse_boolean(value)?, - "RefuseManualStop" => self.RefuseManualStop = basic::config::parse_boolean(value)?, + "Description" => self.Description = value.to_string(), + "Documentation" => self.Documentation = value.to_string(), + "IgnoreOnIsolate" => self.IgnoreOnIsolate = basic::config::parse_boolean(value)?, "DefaultDependencies" => { self.DefaultDependencies = basic::config::parse_boolean(value)? } - "OnSuccessJobMode" => self.OnSuccessJobMode = JobMode::parse_from_str(value)?, + "RefuseManualStart" => self.RefuseManualStart = basic::config::parse_boolean(value)?, + "RefuseManualStop" => self.RefuseManualStop = basic::config::parse_boolean(value)?, "OnFailureJobMode" => self.OnFailureJobMode = JobMode::parse_from_str(value)?, - "IgnoreOnIsolate" => self.IgnoreOnIsolate = basic::config::parse_boolean(value)?, - "JobTimeoutAction" => { - self.JobTimeoutAction = UnitEmergencyAction::parse_from_str(value)? - } - "StartLimitBurst" => self.StartLimitBurst = value.parse::()?, - "StartLimitAction" => { - self.StartLimitAction = UnitEmergencyAction::parse_from_str(value)? - } - "FailureAction" => self.FailureAction = UnitEmergencyAction::parse_from_str(value)?, - "SuccessAction" => self.SuccessAction = UnitEmergencyAction::parse_from_str(value)?, + "OnSuccessJobMode" => self.OnSuccessJobMode = JobMode::parse_from_str(value)?, + "Wants" => self.Wants = vec_str_2_string(value), + "Requires" => self.Requires = vec_str_2_string(value), + "BindsTo" => self.BindsTo = vec_str_2_string(value), + "Requisite" => self.Requisite = vec_str_2_string(value), + "PartOf" => self.PartOf = vec_str_2_string(value), + "OnFailure" => self.OnFailure = vec_str_2_string(value), + "OnSuccess" => self.OnSuccess = vec_str_2_string(value), + "Before" => self.Before = vec_str_2_string(value), + "After" => self.After = vec_str_2_string(value), + "Conflicts" => self.Conflicts = vec_str_2_string(value), + + /* Conditions */ "ConditionACPower" => { self.ConditionACPower = Some(basic::config::parse_boolean(value)?) } @@ -288,19 +293,22 @@ impl UeConfigUnit { "ConditionPathIsSymbolicLink" => self.ConditionPathIsSymbolicLink = value.to_string(), "ConditionSecurity" => self.ConditionSecurity = value.to_string(), "ConditionUser" => self.ConditionUser = value.to_string(), + + /* Asserts */ "AssertPathExists" => self.AssertPathExists = value.to_string(), - "Documentation" => self.Documentation = value.to_string(), - "Wants" => self.Wants = vec_str_2_string(value), - "Requires" => self.Requires = vec_str_2_string(value), - "BindsTo" => self.BindsTo = vec_str_2_string(value), - "Requisite" => self.Requisite = vec_str_2_string(value), - "PartOf" => self.PartOf = vec_str_2_string(value), - "OnFailure" => self.OnFailure = vec_str_2_string(value), - "OnSuccess" => self.OnSuccess = vec_str_2_string(value), - "Before" => self.Before = vec_str_2_string(value), - "After" => self.After = vec_str_2_string(value), - "Conflicts" => self.Conflicts = vec_str_2_string(value), - "Description" => self.Description = value.to_string(), + + "StartLimitInterval" => self.StartLimitInterval = value.parse::()?, + "StartLimitIntervalSec" => self.StartLimitIntervalSec = value.parse::()?, + "StartLimitBurst" => self.StartLimitBurst = value.parse::()?, + "SuccessAction" => self.SuccessAction = UnitEmergencyAction::parse_from_str(value)?, + "FailureAction" => self.FailureAction = UnitEmergencyAction::parse_from_str(value)?, + "StartLimitAction" => { + self.StartLimitAction = UnitEmergencyAction::parse_from_str(value)? + } + "JobTimeoutSec" => self.JobTimeoutSec = value.parse::()?, + "JobTimeoutAction" => { + self.JobTimeoutAction = UnitEmergencyAction::parse_from_str(value)? + } str_key => { return Err(Error::NotFound { what: format!("set property:{}", str_key), @@ -311,10 +319,6 @@ impl UeConfigUnit { } } -fn vec_str_2_string(str: &str) -> Vec { - str.split_whitespace().map(|s| s.to_string()).collect() -} - #[derive(UnitSection, Default, Clone, Debug, Serialize, Deserialize)] pub struct UeConfigInstall { #[entry(append)] @@ -328,14 +332,26 @@ pub struct UeConfigInstall { } impl UeConfigInstall { - pub(crate) fn set_property(&mut self, _key: &str, _value: &str) -> Result<()> { - // nothing supported - Err(Error::NotFound { - what: "set unit install property".to_string(), - }) + pub(crate) fn set_property(&mut self, key: &str, value: &str) -> Result<()> { + match key { + "Alias" => self.Alias = vec_str_2_string(value), + "WantedBy" => self.WantedBy = vec_str_2_string(value), + "RequiredBy" => self.RequiredBy = vec_str_2_string(value), + "Also" => self.Also = vec_str_2_string(value), + str_key => { + return Err(Error::NotFound { + what: format!("set property:{}", str_key), + }) + } + }; + Ok(()) } } +fn vec_str_2_string(str: &str) -> Vec { + str.split_whitespace().map(|s| s.to_string()).collect() +} + #[derive(Clone, Debug, Serialize, Deserialize)] struct UnitReConfig { unit: UeConfigUnit, -- Gitee