ldap3_serde/controls_impl/
read_entry.rs1use std::collections::HashMap;
2
3use bytes::BytesMut;
4
5use super::{ControlParser, MakeCritical, RawControl};
6use crate::search::{ResultEntry, SearchEntry};
7use lber_serde::parse::parse_tag;
8use lber_serde::structures::{ASNTag, OctetString, Sequence, Tag};
9use lber_serde::write;
10
11pub const PRE_READ_OID: &str = "1.3.6.1.1.13.1";
12pub const POST_READ_OID: &str = "1.3.6.1.1.13.2";
13
14#[derive(Debug)]
15struct ReadEntry<S> {
16 attrs: Vec<S>,
17 oid: &'static str,
18}
19
20#[derive(Debug)]
25pub struct ReadEntryResp {
26 pub attrs: HashMap<String, Vec<String>>,
28 pub bin_attrs: HashMap<String, Vec<Vec<u8>>>,
30}
31
32pub type PreReadResp = ReadEntryResp;
34
35pub type PostReadResp = ReadEntryResp;
37
38pub struct PreRead<S>(ReadEntry<S>);
40
41impl<S: AsRef<str>> PreRead<S> {
42 #[allow(clippy::new_ret_no_self)]
44 pub fn new(attrs: Vec<S>) -> RawControl {
45 PreRead(ReadEntry {
46 attrs,
47 oid: PRE_READ_OID,
48 })
49 .into()
50 }
51}
52
53impl<S> MakeCritical for PreRead<S> {}
54
55impl<S: AsRef<str>> From<PreRead<S>> for RawControl {
56 fn from(pr: PreRead<S>) -> RawControl {
57 from_read_entry(pr.0)
58 }
59}
60
61pub struct PostRead<S>(ReadEntry<S>);
63
64impl<S> MakeCritical for PostRead<S> {}
65
66impl<S: AsRef<str>> PostRead<S> {
67 #[allow(clippy::new_ret_no_self)]
69 pub fn new(attrs: Vec<S>) -> RawControl {
70 PostRead(ReadEntry {
71 attrs,
72 oid: POST_READ_OID,
73 })
74 .into()
75 }
76}
77
78impl<S: AsRef<str>> From<PostRead<S>> for RawControl {
79 fn from(pr: PostRead<S>) -> RawControl {
80 from_read_entry(pr.0)
81 }
82}
83
84fn from_read_entry<S: AsRef<str>>(re: ReadEntry<S>) -> RawControl {
85 let mut attr_vec = Vec::new();
86 let mut enc_size_est = 2;
87 for attr in re.attrs {
88 enc_size_est += attr.as_ref().len() + 2;
89 let tag = Tag::OctetString(OctetString {
90 inner: Vec::from(attr.as_ref()),
91 ..Default::default()
92 });
93 attr_vec.push(tag);
94 }
95 let cval = Tag::Sequence(Sequence {
96 inner: attr_vec,
97 ..Default::default()
98 })
99 .into_structure();
100 let mut buf = BytesMut::with_capacity(enc_size_est);
101 write::encode_into(&mut buf, cval).expect("encoded");
102 RawControl {
103 ctype: re.oid.to_owned(),
104 crit: false,
105 val: Some(Vec::from(&buf[..])),
106 }
107}
108
109impl ControlParser for ReadEntryResp {
110 fn parse(val: &[u8]) -> ReadEntryResp {
111 let tag = match parse_tag(val) {
112 Ok((_, tag)) => tag,
113 _ => panic!("failed to parse pre-read attribute values"),
114 };
115 let se = SearchEntry::construct(ResultEntry::new(tag));
116 ReadEntryResp {
117 attrs: se.attrs,
118 bin_attrs: se.bin_attrs,
119 }
120 }
121}