ldap_rs/
controls.rs

1//! LDAP controls
2
3use std::convert::TryFrom;
4
5use rasn::{ber, types::*, Decode, Decoder, Encode};
6use rasn_ldap::Control;
7
8use crate::error::Error;
9
10/// Simple paged result control, OID 1.2.840.113556.1.4.319
11#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
12pub struct SimplePagedResultsControl {
13    size: Integer,
14    cookie: OctetString,
15    has_entries: bool,
16}
17
18impl SimplePagedResultsControl {
19    /// Control OID
20    pub const OID: &'static [u8] = crate::oid::SIMPLE_PAGED_RESULTS_CONTROL_OID;
21
22    /// Create paged result control with a given page size
23    pub fn new(size: u32) -> Self {
24        Self {
25            size: size.into(),
26            cookie: OctetString::default(),
27            has_entries: true,
28        }
29    }
30
31    /// Replace the page size for a given control
32    pub fn with_size(self, size: u32) -> Self {
33        Self {
34            size: size.into(),
35            ..self
36        }
37    }
38
39    /// Return a cookie
40    pub fn cookie(&self) -> &OctetString {
41        &self.cookie
42    }
43
44    /// Return a current size
45    pub fn size(&self) -> &Integer {
46        &self.size
47    }
48
49    /// Returns true if this control indicates more entries are available
50    pub fn has_entries(&self) -> bool {
51        self.has_entries
52    }
53}
54
55#[derive(AsnType, Encode, Decode, Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
56struct RealSearchControlValue {
57    size: Integer,
58    cookie: OctetString,
59}
60
61impl TryFrom<SimplePagedResultsControl> for Control {
62    type Error = Error;
63
64    fn try_from(control: SimplePagedResultsControl) -> Result<Self, Self::Error> {
65        let value = RealSearchControlValue {
66            size: control.size,
67            cookie: control.cookie,
68        };
69        Ok(Control::new(
70            SimplePagedResultsControl::OID.into(),
71            false,
72            Some(ber::encode(&value)?.into()),
73        ))
74    }
75}
76
77impl TryFrom<Control> for SimplePagedResultsControl {
78    type Error = Error;
79
80    fn try_from(value: Control) -> Result<Self, Self::Error> {
81        let value = ber::decode::<RealSearchControlValue>(value.control_value.as_deref().unwrap_or(b""))?;
82        let has_entries = !value.cookie.is_empty();
83
84        Ok(SimplePagedResultsControl {
85            size: value.size,
86            cookie: value.cookie,
87            has_entries,
88        })
89    }
90}