netconf/message/rpc/operation/
kill_session.rs

1use std::io::Write;
2
3use quick_xml::{events::BytesText, Writer};
4
5use crate::{
6    capabilities::Requirements,
7    message::WriteError,
8    session::{Context, SessionId},
9    Error,
10};
11
12use super::{params::Required, EmptyReply, Operation, WriteXml};
13
14#[derive(Debug, Clone, Copy)]
15pub struct KillSession {
16    session_id: SessionId,
17}
18
19impl Operation for KillSession {
20    const NAME: &'static str = "kill-session";
21    const REQUIRED_CAPABILITIES: Requirements = Requirements::None;
22
23    type Builder<'a> = Builder<'a>;
24    type Reply = EmptyReply;
25}
26
27impl WriteXml for KillSession {
28    fn write_xml<W: Write>(&self, writer: &mut Writer<W>) -> Result<(), WriteError> {
29        writer
30            .create_element(Self::NAME)
31            .write_inner_content(|writer| {
32                _ = writer
33                    .create_element("session-id")
34                    .write_text_content(BytesText::new(&self.session_id.to_string()))?;
35                Ok(())
36            })
37            .map(|_| ())
38    }
39}
40
41#[derive(Debug, Clone)]
42#[must_use]
43pub struct Builder<'a> {
44    ctx: &'a Context,
45    session_id: Required<SessionId>,
46}
47
48impl Builder<'_> {
49    pub fn session_id(mut self, session_id: u32) -> Result<Self, Error> {
50        SessionId::new(session_id).and_then(|session_id| {
51            if session_id == self.ctx.session_id() {
52                Err(Error::KillCurrentSession)
53            } else {
54                self.session_id.set(session_id);
55                Ok(self)
56            }
57        })
58    }
59}
60
61impl<'a> super::Builder<'a, KillSession> for Builder<'a> {
62    fn new(ctx: &'a Context) -> Self {
63        Self {
64            ctx,
65            session_id: Required::init(),
66        }
67    }
68
69    fn finish(self) -> Result<KillSession, Error> {
70        Ok(KillSession {
71            session_id: self.session_id.require::<KillSession>("session-id")?,
72        })
73    }
74}
75
76#[cfg(test)]
77mod tests {
78    use super::*;
79    use crate::message::{
80        rpc::{MessageId, Request},
81        ClientMsg,
82    };
83
84    #[test]
85    fn lock_request_to_xml() {
86        let req = Request {
87            message_id: MessageId(101),
88            operation: KillSession {
89                session_id: SessionId::new(999).unwrap(),
90            },
91        };
92        let expect = r#"<rpc message-id="101"><kill-session><session-id>999</session-id></kill-session></rpc>]]>]]>"#;
93        assert_eq!(req.to_xml().unwrap(), expect);
94    }
95}