1use std::convert::TryFrom;
4
5use rasn::{ber, types::*, Decode, Decoder, Encode};
6use rasn_ldap::Control;
7
8use crate::error::Error;
9
10#[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 pub const OID: &'static [u8] = crate::oid::SIMPLE_PAGED_RESULTS_CONTROL_OID;
21
22 pub fn new(size: u32) -> Self {
24 Self {
25 size: size.into(),
26 cookie: OctetString::default(),
27 has_entries: true,
28 }
29 }
30
31 pub fn with_size(self, size: u32) -> Self {
33 Self {
34 size: size.into(),
35 ..self
36 }
37 }
38
39 pub fn cookie(&self) -> &OctetString {
41 &self.cookie
42 }
43
44 pub fn size(&self) -> &Integer {
46 &self.size
47 }
48
49 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}