1use crate::error::{LocalError, LocalResult};
5use crate::prefs::ImplementationPrefs;
6
7use rasn::ber::de::DecodeErrorKind;
8use rasn::prelude::*;
9use rasn::AsnType;
10
11#[derive(Debug, Clone, PartialEq, Default, AsnType, Decode, Encode)]
12#[rasn(tag(context, 20))]
13pub struct InitializeRequest {
14 #[rasn(tag(2))]
15 pub reference_id: Option<OctetString>,
16 #[rasn(tag(3))]
17 pub protocol_version: BitString,
18 #[rasn(tag(4))]
19 pub options: BitString,
20 #[rasn(tag(5))]
21 pub preferred_message_size: u32,
22 #[rasn(tag(6))]
23 pub exceptional_record_size: u32,
24 #[rasn(tag(110))]
25 pub implementation_id: Option<String>,
26 #[rasn(tag(111))]
27 pub implementation_name: Option<String>,
28 #[rasn(tag(112))]
29 pub implementation_version: Option<String>,
30}
31
32#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
33#[rasn(tag(context, 21))]
34pub struct InitializeResponse {
35 #[rasn(tag(2))]
36 pub reference_id: Option<OctetString>,
37 #[rasn(tag(3))]
38 pub protocol_version: BitString,
39 #[rasn(tag(4))]
40 pub options: BitString,
41 #[rasn(tag(5))]
42 pub preferred_message_size: u32,
43 #[rasn(tag(6))]
44 pub exceptional_record_size: u32,
45 #[rasn(tag(12))]
46 pub result: Option<bool>,
47 #[rasn(tag(110))]
48 pub implementation_id: Option<String>,
49 #[rasn(tag(111))]
50 pub implementation_name: Option<String>,
51 #[rasn(tag(112))]
52 pub implementation_version: Option<String>,
53}
54
55impl Default for InitializeResponse {
57 fn default() -> Self {
58 let settings = ImplementationPrefs::global();
59
60 let mut options = BitString::repeat(false, 16);
62 for (idx, val) in settings
63 .init_options
64 .as_positioned_values()
65 .iter()
66 .enumerate()
67 {
68 if *val {
69 options.set(idx, true);
70 }
71 }
72
73 InitializeResponse {
74 reference_id: None,
75 protocol_version: BitString::repeat(true, 3),
76 options,
77 result: Some(true),
78 preferred_message_size: settings.preferred_message_size,
79 exceptional_record_size: settings.exceptional_record_size,
80 implementation_id: settings.implementation_id.clone(),
81 implementation_name: settings.implementation_name.clone(),
82 implementation_version: settings.implementation_version.clone(),
83 }
84 }
85}
86
87#[derive(Debug, Clone, Copy, PartialEq, AsnType, Decode, Encode)]
88#[rasn(enumerated)]
89pub enum KnownProximityUnit {
90 Character = 1,
91 Word,
92 Sentence,
93 Paragraph,
94 Section,
95 Chapter,
96 Document,
97 Element,
98 Subelement,
99 ElementType,
100 Byte,
101}
102
103#[derive(Debug, Clone, Copy, PartialEq, AsnType, Decode, Encode)]
104#[rasn(enumerated)]
105pub enum RelationType {
106 LessThan = 1,
107 LessThanOrEqual,
108 Equal,
109 GreaterThanOrEqual,
110 GreaterThan,
111 NotEqual,
112}
113
114#[derive(Debug, Clone, Copy, PartialEq, AsnType, Decode, Encode)]
115#[rasn(enumerated)]
116pub enum ResultSetStatus {
117 Empty = 1,
118 Interim,
119 Unchanged,
120 None,
121}
122
123#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
124#[rasn(choice)]
125pub enum ProximityUnitCode {
126 #[rasn(tag(0))]
127 Known(KnownProximityUnit),
128 #[rasn(tag(1))]
129 Private(u32),
130}
131
132#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
133pub struct ProximityOperator {
134 #[rasn(tag(1))]
135 pub exclusion: bool,
136 #[rasn(tag(2))]
137 pub distance: u32,
138 #[rasn(tag(3))]
139 pub ordered: bool,
140 #[rasn(tag(4))]
141 pub relation_type: RelationType,
142 #[rasn(tag(5))]
143 pub proximity_unit_code: ProximityUnitCode,
144}
145
146#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
149#[rasn(choice)]
150pub enum DatabaseName {
151 #[rasn(tag(105))]
152 Name(String),
153}
154
155#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
156#[rasn(choice)]
157pub enum ElementSetName {
158 #[rasn(tag(103))]
159 Name(String),
160}
161
162#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
163pub struct DatabaseSpecific {
164 pub db_name: DatabaseName,
165 pub esn: ElementSetName,
166}
167
168#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
169#[rasn(choice)]
170pub enum ElementSetNames {
171 #[rasn(tag(0))]
172 GenericElementSetName(String),
173 #[rasn(tag(1))]
174 DatabaseSpecific(Vec<DatabaseSpecific>),
175}
176
177#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
178#[rasn(choice)]
179pub enum StringOrNumeric {
180 #[rasn(tag(1))]
181 String(String),
182 #[rasn(tag(2))]
183 Numeric(u32),
184}
185
186#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
187pub struct ComplexAttributeValue {
188 #[rasn(tag(1))]
189 pub list: Vec<StringOrNumeric>,
190 #[rasn(tag(2))]
191 pub semantic_action: Option<Vec<u32>>,
192}
193
194#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
195#[rasn(choice)]
196pub enum AttributeValue {
197 #[rasn(tag(121))]
198 Numeric(u32),
199 #[rasn(tag(224))]
200 Complex(ComplexAttributeValue),
201}
202
203#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
204#[rasn(choice)]
205pub enum Operator {
209 #[rasn(tag(0))]
210 And,
211 #[rasn(tag(1))]
212 Or,
213 #[rasn(tag(2))]
214 AndNot,
215 #[rasn(tag(3))]
216 Prox(ProximityOperator),
217}
218
219#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
220pub struct Unit {
221 #[rasn(tag(1))]
222 pub unit_system: Option<String>,
223 #[rasn(tag(2))]
224 pub unit_type: Option<StringOrNumeric>,
225 #[rasn(tag(3))]
226 pub unit: Option<StringOrNumeric>,
227 #[rasn(tag(4))]
228 pub scale_factor: Option<u32>,
229}
230
231#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
232pub struct IntUnit {
233 #[rasn(tag(1))]
234 pub value: u32,
235 #[rasn(tag(2))]
236 pub unit_used: Unit,
237}
238
239#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
240#[rasn(choice)]
241pub enum Term {
242 #[rasn(tag(45))]
243 General(OctetString),
244 #[rasn(tag(215))]
245 Numeric(u32),
246 #[rasn(tag(216))]
247 CharacterString(String),
248 #[rasn(tag(217))]
249 Oid(ObjectIdentifier),
250 #[rasn(tag(218))]
251 DateTime(GeneralizedTime),
252 #[rasn(tag(219))]
253 External(Any),
254 #[rasn(tag(220))]
255 IntegerAndUnit(IntUnit),
256 #[rasn(tag(221))]
257 Null,
258}
259
260impl Term {
261 pub fn general_from_str(s: &str) -> Term {
262 Term::General(OctetString::copy_from_slice(s.as_bytes()))
263 }
264}
265
266#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
267pub struct AttributeElement {
268 #[rasn(tag(1))]
269 pub attribute_set: Option<ObjectIdentifier>,
270 #[rasn(tag(120))]
271 pub attribute_type: u32,
272 pub attribute_value: AttributeValue,
273}
274
275#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
276pub struct ResultSetPlusAttributes {
277 pub result_set: ObjectIdentifier,
278 #[rasn(tag(44))]
279 pub attributes: Vec<AttributeElement>,
280}
281
282#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
283pub struct AttributesPlusTerm {
284 #[rasn(tag(44))]
285 pub attributes: Vec<AttributeElement>,
286 pub term: Term,
287}
288
289#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
290#[rasn(choice)]
291pub enum Operand {
292 #[rasn(tag(102))]
293 AttrTerm(AttributesPlusTerm),
294 #[rasn(tag(31))]
295 ResultSet(String),
296 #[rasn(tag(214))]
297 ResultAttr(ResultSetPlusAttributes),
298}
299
300#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
301pub struct RpnOp {
302 pub rpn1: RpnStructure,
303 pub rpn2: RpnStructure,
304 #[rasn(tag(46))]
305 pub op: Operator,
306}
307
308#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
309#[rasn(choice)]
310pub enum RpnStructure {
311 #[rasn(tag(0))]
312 Op(Operand),
313 #[rasn(tag(1))]
314 RpnOp(Box<RpnOp>),
315}
316
317#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
318pub struct RpnQuery {
319 pub attribute_set: ObjectIdentifier,
320 pub rpn: RpnStructure,
321}
322
323#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
324#[rasn(choice)]
325pub enum Query {
326 #[rasn(tag(0))]
327 Type0(Any),
328 #[rasn(tag(1))]
329 Type1(RpnQuery),
330 #[rasn(tag(2))]
331 Type2(OctetString),
332 #[rasn(tag(100))]
333 Type100(OctetString),
334 #[rasn(tag(101))]
335 Type101(RpnQuery),
336 #[rasn(tag(102))]
337 Type102(OctetString),
338}
339
340#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
341#[rasn(choice)]
342pub enum Information {
343 #[rasn(tag(2))]
344 CharacterInfo(String),
345 #[rasn(tag(3))]
346 BinaryInfo(OctetString),
347 #[rasn(tag(4))]
348 ExternallyDefinedInfo(Any),
349 #[rasn(tag(5))]
350 Oid(ObjectIdentifier),
351}
352
353#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
354pub struct InfoCategory {
355 #[rasn(tag(1))]
356 pub category_type_id: Option<ObjectIdentifier>,
357 #[rasn(tag(2))]
358 pub category_value: Option<u32>,
359}
360
361#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
362#[rasn(tag(201))]
363pub struct OtherInformation {
364 #[rasn(tag(1))]
365 pub category: Option<InfoCategory>,
366 pub information: Information,
367}
368
369#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
370#[rasn(tag(context, 22))]
371pub struct SearchRequest {
372 #[rasn(tag(2))]
373 pub reference_id: Option<OctetString>,
374 #[rasn(tag(13))]
375 pub small_set_upper_bound: u32,
376 #[rasn(tag(14))]
377 pub large_set_lower_bound: u32,
378 #[rasn(tag(15))]
379 pub medium_set_present_number: u32,
380 #[rasn(tag(16))]
381 pub replace_indicator: bool,
382 #[rasn(tag(17))]
383 pub result_set_name: String,
384 #[rasn(tag(18))]
385 pub database_names: Vec<DatabaseName>,
386 #[rasn(tag(21))]
387 pub query: Query,
388 #[rasn(tag(100))]
389 pub small_set_element_names: Option<ElementSetNames>,
390 #[rasn(tag(101))]
391 pub medium_set_element_names: Option<ElementSetNames>,
392 #[rasn(tag(104))]
393 pub preferred_record_syntax: Option<ObjectIdentifier>,
394 #[rasn(tag(203))]
395 pub additional_search_info: Option<OtherInformation>,
396}
397
398#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
399#[rasn(choice)]
400pub enum AddInfo {
401 V2AddInfo(VisibleString),
402 V3AddInfo(GeneralString),
403}
404
405#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
406pub struct DefaultDiagFormat {
407 pub diagnostic_set_id: ObjectIdentifier,
408 pub condition: u32,
409 pub addinfo: AddInfo,
410}
411
412#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
413#[rasn(choice)]
414pub enum DiagRec {
415 DefaultFormat(DefaultDiagFormat),
416 ExternallyDefined(Any),
417}
418
419#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
420#[rasn(choice)]
421pub enum FragmentSyntax {
422 ExternallyTagged(Any),
423 NotExternallyTagged(OctetString),
424}
425
426#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
427#[rasn(choice)]
428pub enum Encoding {
429 #[rasn(tag(0))]
430 SingleAsn1Type(Any),
431 #[rasn(tag(1))]
432 OctetAligned(OctetString),
433 #[rasn(tag(2))]
434 Arbitrary(BitString),
435}
436
437#[derive(Debug, Clone, PartialEq, AsnType, Encode, Decode)]
438#[rasn(tag(universal, 8))]
439pub struct ExternalMessage {
440 pub direct_reference: Option<ObjectIdentifier>,
441 pub indirect_reference: Option<u32>,
442 pub data_value_descriptor: Option<String>,
443 pub encoding: Encoding,
444}
445
446impl ExternalMessage {
447 pub fn new(encoding: Encoding) -> Self {
448 Self {
449 direct_reference: None,
450 indirect_reference: None,
451 data_value_descriptor: None,
452 encoding,
453 }
454 }
455}
456
457#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
464pub struct External(pub ExternalMessage);
465
466#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
467#[rasn(choice)]
468pub enum Record {
469 #[rasn(tag(1))]
470 RetrievalRecord(External),
471 #[rasn(tag(2))]
472 SurrogateDiagnostic(DiagRec),
473 #[rasn(tag(3))]
474 StartingFragment(FragmentSyntax),
475 #[rasn(tag(4))]
476 IntermediateFragment(FragmentSyntax),
477 #[rasn(tag(5))]
478 FinalFragment(FragmentSyntax),
479}
480
481#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
482pub struct NamePlusRecord {
483 #[rasn(tag(0))]
484 pub name: Option<DatabaseName>,
485 #[rasn(tag(1))]
486 pub record: Record,
487}
488
489impl NamePlusRecord {
490 pub fn new(record: Record) -> Self {
491 Self { name: None, record }
492 }
493}
494
495#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
496#[rasn(choice)]
497pub enum Records {
498 #[rasn(tag(28))]
499 ResponseRecords(Vec<NamePlusRecord>),
500 #[rasn(tag(130))]
501 NonSurrogateDiagnostic(DefaultDiagFormat),
502 #[rasn(tag(205))]
503 MultipleNonSurDiagnostics(Vec<DiagRec>),
504}
505
506#[derive(Debug, Clone, PartialEq, Default, AsnType, Decode, Encode)]
507#[rasn(tag(context, 23))]
508pub struct SearchResponse {
509 #[rasn(tag(2))]
510 pub reference_id: Option<OctetString>,
511 #[rasn(tag(23))]
512 pub result_count: u32,
513 #[rasn(tag(24))]
514 pub number_of_records_returned: u32,
515 #[rasn(tag(25))]
516 pub next_result_set_position: u32,
517 #[rasn(tag(22))]
518 pub search_status: bool,
519 #[rasn(tag(26))]
520 pub result_set_status: Option<ResultSetStatus>,
521 #[rasn(tag(27))]
522 pub present_status: Option<PresentStatus>,
523 pub records: Option<Records>,
524 #[rasn(tag(203))]
525 pub additional_search_info: Option<OtherInformation>,
526 pub other_info: Option<OtherInformation>,
527}
528
529#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
530pub struct Range {
531 #[rasn(tag(1))]
532 pub starting_position: u32,
533 #[rasn(tag(2))]
534 pub number_of_records: u32,
535}
536
537#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
538pub struct ElementSpec {
539 #[rasn(tag(1))]
540 pub element_set_name: String,
541 #[rasn(tag(2))]
542 pub external_espec: Option<Any>,
543}
544
545#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
546pub struct Specification {
547 #[rasn(tag(1))]
548 pub schema: Option<ObjectIdentifier>,
549 #[rasn(tag(2))]
550 pub element_spec: Option<ElementSpec>,
551}
552
553#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
554pub struct CompSpecDatabaseSpecific {
555 #[rasn(tag(1))]
556 pub db: DatabaseName,
557 #[rasn(tag(2))]
558 pub spec: Specification,
559}
560
561#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
562pub struct CompSpec {
563 #[rasn(tag(1))]
564 pub select_alternative_syntax: bool,
565 #[rasn(tag(2))]
566 pub generic: Option<Specification>,
567 #[rasn(tag(3))]
568 pub db_specific: Option<CompSpecDatabaseSpecific>,
569 #[rasn(tag(4))]
570 pub record_syntax: Option<Vec<ObjectIdentifier>>,
571}
572
573#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
574#[rasn(choice)]
575pub enum RecordComposition {
576 #[rasn(tag(19))]
577 Simple(ElementSetNames),
578 #[rasn(tag(209))]
579 Complex(CompSpec),
580}
581
582#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
583#[rasn(tag(context, 24))]
584pub struct PresentRequest {
585 #[rasn(tag(2))]
586 pub reference_id: Option<OctetString>,
587 #[rasn(tag(31))]
588 pub result_set_id: String,
589 #[rasn(tag(30))]
590 pub reset_set_start_point: u32,
591 #[rasn(tag(29))]
592 pub number_of_records_requested: u32,
593 #[rasn(tag(212))]
594 pub additional_ranges: Option<Vec<Range>>,
595 pub record_composition: Option<RecordComposition>,
596 #[rasn(tag(104))]
597 pub preferred_record_syntax: Option<ObjectIdentifier>,
598 #[rasn(tag(204))]
599 pub max_segment_count: Option<u32>,
600 #[rasn(tag(206))]
601 pub max_record_size: Option<u32>,
602 #[rasn(tag(207))]
603 pub max_segment_size: Option<u32>,
604 pub other_info: Option<OtherInformation>,
605}
606
607#[derive(Debug, Clone, Copy, PartialEq, AsnType, Decode, Encode)]
608#[rasn(enumerated)]
609pub enum PresentStatus {
610 Success = 0,
611 Partial1,
612 Partial2,
613 Partial3,
614 Partial4,
615 Failure,
616}
617
618#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
619#[rasn(tag(context, 25))]
620pub struct PresentResponse {
621 #[rasn(tag(2))]
622 pub reference_id: Option<OctetString>,
623 #[rasn(tag(24))]
624 pub number_of_records_returned: u32,
625 #[rasn(tag(25))]
626 pub next_result_set_position: u32,
627 #[rasn(tag(27))]
628 pub present_status: PresentStatus,
629 pub records: Option<Records>,
630 pub other_info: Option<OtherInformation>,
631}
632
633impl Default for PresentResponse {
634 fn default() -> Self {
635 PresentResponse {
636 reference_id: None,
637 number_of_records_returned: 0,
638 next_result_set_position: 0,
639 present_status: PresentStatus::Success,
640 records: None,
641 other_info: None,
642 }
643 }
644}
645
646#[derive(Debug, Clone, Copy, PartialEq, AsnType, Decode, Encode)]
647#[rasn(enumerated)]
648pub enum CloseReason {
649 Finished = 0,
650 Shutdown,
651 SystemProblem,
652 CostLimit,
653 Resources,
654 SecurityViolation,
655 ProtocolError,
656 LackOfActivity,
657 PeerAbort,
658 Unspecified,
659}
660
661#[derive(Debug, Clone, PartialEq, AsnType, Decode, Encode)]
662#[rasn(tag(context, 48))]
663pub struct Close {
664 #[rasn(tag(2))]
665 pub reference_id: Option<OctetString>,
666 #[rasn(tag(211))]
667 pub close_reason: CloseReason,
668 #[rasn(tag(3))]
669 pub diagnostic_information: Option<String>,
670 #[rasn(tag(4))]
671 pub resource_report_format: Option<ObjectIdentifier>,
672 #[rasn(tag(5))]
673 pub resource_report: Option<External>,
674 pub other_info: Option<OtherInformation>,
675}
676
677impl Default for Close {
678 fn default() -> Self {
679 Self {
680 reference_id: None,
681 close_reason: CloseReason::Finished,
682 diagnostic_information: None,
683 resource_report_format: None,
684 resource_report: None,
685 other_info: None,
686 }
687 }
688}
689
690#[derive(Debug, Clone, PartialEq)]
691pub enum MessagePayload {
692 InitializeRequest(InitializeRequest),
693 InitializeResponse(InitializeResponse),
694 SearchRequest(SearchRequest),
695 SearchResponse(SearchResponse),
696 PresentRequest(PresentRequest),
697 PresentResponse(PresentResponse),
698 Close(Close),
699}
700
701#[derive(Debug, Clone, PartialEq)]
704pub struct Message {
705 pub payload: MessagePayload,
706}
707
708impl Message {
709 pub fn from_bytes(bytes: &[u8]) -> LocalResult<Option<Self>> {
714 if bytes.is_empty() {
715 return Ok(None);
716 }
717
718 let handle_error = |e: rasn::error::DecodeError| match *e.kind {
721 DecodeErrorKind::Incomplete { needed: _ } => Ok(None),
722 _ => Err(LocalError::DecodeError(e)),
723 };
724
725 let tag = if bytes[0] == 191 {
741 bytes[1]
743 } else if bytes[0] >= 180 {
744 bytes[0] - 160
745 } else {
746 0
747 };
748
749 let payload = match tag {
750 20 => match rasn::ber::decode(bytes) {
751 Ok(m) => MessagePayload::InitializeRequest(m),
752 Err(e) => return handle_error(e),
753 },
754 21 => match rasn::ber::decode(bytes) {
755 Ok(m) => MessagePayload::InitializeResponse(m),
756 Err(e) => return handle_error(e),
757 },
758 22 => match rasn::ber::decode(bytes) {
759 Ok(m) => MessagePayload::SearchRequest(m),
760 Err(e) => return handle_error(e),
761 },
762 23 => match rasn::ber::decode(bytes) {
763 Ok(m) => MessagePayload::SearchResponse(m),
764 Err(e) => return handle_error(e),
765 },
766 24 => match rasn::ber::decode(bytes) {
767 Ok(m) => MessagePayload::PresentRequest(m),
768 Err(e) => return handle_error(e),
769 },
770 25 => match rasn::ber::decode(bytes) {
771 Ok(m) => MessagePayload::PresentResponse(m),
772 Err(e) => return handle_error(e),
773 },
774 48 => match rasn::ber::decode(bytes) {
775 Ok(m) => MessagePayload::Close(m),
776 Err(e) => return handle_error(e),
777 },
778 _ => {
779 return Err(LocalError::ProtocolError(format!(
780 "Cannot process message with first byte: {}",
781 bytes[0]
782 )))
783 }
784 };
785
786 Ok(Some(Message { payload }))
787 }
788
789 pub fn from_payload(payload: MessagePayload) -> Self {
791 Message { payload }
792 }
793
794 pub fn to_bytes(&self) -> LocalResult<Vec<u8>> {
797 let res = match &self.payload {
798 MessagePayload::InitializeRequest(m) => rasn::ber::encode(&m),
799 MessagePayload::InitializeResponse(m) => rasn::ber::encode(&m),
800 MessagePayload::SearchRequest(m) => rasn::ber::encode(&m),
801 MessagePayload::SearchResponse(m) => rasn::ber::encode(&m),
802 MessagePayload::PresentRequest(m) => rasn::ber::encode(&m),
803 MessagePayload::PresentResponse(m) => rasn::ber::encode(&m),
804 MessagePayload::Close(m) => rasn::ber::encode(&m),
805 };
806
807 res.map_err(LocalError::EncodeError)
808 }
809}