netconf/message/rpc/operation/
copy_config.rs1use std::io::Write;
2
3use quick_xml::Writer;
4
5use crate::{capabilities::Requirements, message::WriteError, session::Context, Error};
6
7use super::{params::Required, Datastore, EmptyReply, Operation, Source, WriteXml};
8
9#[derive(Debug, Clone)]
10pub struct CopyConfig {
11 target: Target,
12 source: Source,
13}
14
15impl Operation for CopyConfig {
16 const NAME: &'static str = "copy-config";
17 const REQUIRED_CAPABILITIES: Requirements = Requirements::None;
18
19 type Builder<'a> = Builder<'a>;
20 type Reply = EmptyReply;
21}
22
23impl WriteXml for CopyConfig {
24 fn write_xml<W: Write>(&self, writer: &mut Writer<W>) -> Result<(), WriteError> {
25 writer
26 .create_element(Self::NAME)
27 .write_inner_content(|writer| {
28 _ = writer
29 .create_element("target")
30 .write_inner_content(|writer| self.target.write_xml(writer))?;
31 _ = writer
32 .create_element("source")
33 .write_inner_content(|writer| self.source.write_xml(writer))?;
34 Ok(())
35 })
36 .map(|_| ())
37 }
38}
39
40#[derive(Debug, Clone)]
41#[must_use]
42pub struct Builder<'a> {
43 ctx: &'a Context,
44 target: Required<Target>,
45 source: Required<Source>,
46}
47
48impl Builder<'_> {
49 pub fn target(mut self, target: Datastore) -> Result<Self, Error> {
50 target.try_as_target(self.ctx).map(|target| {
51 self.target.set(Target::Datastore(target));
52 self
53 })
54 }
55
56 pub fn source(mut self, source: Datastore) -> Result<Self, Error> {
57 source.try_as_source(self.ctx).map(|source| {
58 self.source.set(Source::Datastore(source));
59 self
60 })
61 }
62
63 pub fn config(mut self, config: String) -> Self {
64 self.source.set(Source::Config(config));
65 self
66 }
67}
68
69impl<'a> super::Builder<'a, CopyConfig> for Builder<'a> {
70 fn new(ctx: &'a Context) -> Self {
71 Self {
72 ctx,
73 target: Required::init(),
74 source: Required::init(),
75 }
76 }
77
78 fn finish(self) -> Result<CopyConfig, Error> {
79 Ok(CopyConfig {
80 target: self.target.require::<CopyConfig>("target")?,
81 source: self.source.require::<CopyConfig>("source")?,
82 })
83 }
84}
85
86#[derive(Debug, Clone)]
87enum Target {
88 Datastore(Datastore),
89}
90
91impl WriteXml for Target {
92 fn write_xml<W: Write>(&self, writer: &mut Writer<W>) -> Result<(), WriteError> {
93 match self {
94 Self::Datastore(datastore) => datastore.write_xml(writer),
95 }
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102 use crate::message::{
103 rpc::{MessageId, Request},
104 ClientMsg,
105 };
106
107 #[test]
108 fn request_to_xml() {
109 let req = Request {
110 message_id: MessageId(101),
111 operation: CopyConfig {
112 target: Target::Datastore(Datastore::Running),
113 source: Source::Config("<foo>bar</foo>".to_string()),
114 },
115 };
116 let expect = r#"<rpc message-id="101"><copy-config><target><running/></target><source><config><foo>bar</foo></config></source></copy-config></rpc>]]>]]>"#;
117 assert_eq!(req.to_xml().unwrap(), expect);
118 }
119}