1use rasn::types::{Any, BitString, GeneralizedTime, Integer, ObjectIdentifier, OctetString, Utf8String, VisibleString};
2use rasn::{AsnType, Decode, Decoder, Encode, Encoder};
3
4use crate::error::{Error, Result};
5
6#[derive(AsnType, Encode, Decode, Debug)]
7#[rasn(choice)]
8pub enum DatabaseName {
9 #[rasn(tag(context, 105))] General(VisibleString),
11}
12
13#[derive(Debug, Clone)]
15pub struct Credentials {
16 pub username: String,
17 pub password: String,
18}
19
20impl Credentials {
21 pub fn new(username: impl Into<String>, password: impl Into<String>) -> Self {
22 Self {
23 username: username.into(),
24 password: password.into(),
25 }
26 }
27}
28
29#[derive(Debug, AsnType, Encode, Decode)]
30#[rasn(choice)]
31pub enum Apdu {
32 #[rasn(tag(context, 20))]
33 InitRequest(InitRequest),
34 #[rasn(tag(context, 21))]
35 InitResponse(InitResponse),
36 #[rasn(tag(context, 22))]
37 SearchRequest(SearchRequest),
38 #[rasn(tag(context, 23))]
39 SearchResponse(SearchResponse),
40 #[rasn(tag(context, 24))]
41 PresentRequest(PresentRequest),
42 #[rasn(tag(context, 25))]
43 PresentResponse(PresentResponse),
44 #[rasn(tag(context, 26))]
45 DeleteResultSetRequest(DeleteResultSetRequest),
46 #[rasn(tag(context, 27))]
47 DeleteResultSetResponse(DeleteResultSetResponse),
48 #[rasn(tag(context, 28))]
49 AccessControlRequest(AccessControlRequest),
50 #[rasn(tag(context, 29))]
51 AccessControlResponse(AccessControlResponse),
52 #[rasn(tag(context, 30))]
53 ResourceControlRequest(ResourceControlRequest),
54 #[rasn(tag(context, 31))]
55 ResourceControlResponse(ResourceControlResponse),
56 #[rasn(tag(context, 32))]
57 TriggerResourceControlRequest(TriggerResourceControlRequest),
58 #[rasn(tag(context, 33))]
59 ResourceReportRequest(ResourceReportRequest),
60 #[rasn(tag(context, 34))]
61 ResourceReportResponse(ResourceReportResponse),
62 #[rasn(tag(context, 35))]
63 ScanRequest(ScanRequest),
64 #[rasn(tag(context, 36))]
65 ScanResponse(ScanResponse),
66 #[rasn(tag(context, 43))]
67 SortRequest(SortRequest),
68 #[rasn(tag(context, 44))]
69 SortResponse(SortResponse),
70 #[rasn(tag(context, 45))]
71 Segment(Segment),
72 #[rasn(tag(context, 46))]
73 ExtendedServicesRequest(ExtendedServicesRequest),
74 #[rasn(tag(context, 47))]
75 ExtendedServicesResponse(ExtendedServicesResponse),
76 #[rasn(tag(context, 48))]
77 Close(Close),
78 #[rasn(tag(context, 49))]
79 DuplicateDetectionRequest(DuplicateDetectionRequest),
80 #[rasn(tag(context, 50))]
81 DuplicateDetectionResponse(DuplicateDetectionResponse),
82}
83
84#[derive(Debug, AsnType, Encode, Decode)]
85#[rasn(tag(20))]
86pub struct InitRequest {
87 #[rasn(tag(2))]
89 pub reference_id: Option<OctetString>,
90
91 #[rasn(tag(3))]
93 pub protocol_version: BitString,
94
95 #[rasn(tag(4))]
97 pub options: BitString,
98
99 #[rasn(tag(5))]
101 pub preferred_message_size: Integer,
102
103 #[rasn(tag(6))]
105 pub exceptional_record_size: Integer,
106
107 #[rasn(tag(7))]
109 pub id_authentication: Option<IdAuthentication>,
110
111 #[rasn(tag(110))]
113 pub implementation_id: Option<Utf8String>,
114 #[rasn(tag(111))]
115 pub implementation_name: Option<Utf8String>,
116 #[rasn(tag(112))]
117 pub implementation_version: Option<Utf8String>,
118
119 #[rasn(tag(11))]
120 pub user_information_field: Option<OctetString>,
121 pub other_info: Option<OctetString>,
122}
123
124#[derive(Debug, AsnType, Encode, Decode)]
125#[rasn(tag(21))]
126pub struct InitResponse {
127 #[rasn(tag(2))]
128 pub reference_id: Option<OctetString>,
129 #[rasn(tag(3))]
130 pub protocol_version: Option<BitString>,
131 #[rasn(tag(4))]
132 pub options: Option<BitString>,
133 #[rasn(tag(5))]
134 pub preferred_message_size: Option<Integer>,
135 #[rasn(tag(6))]
136 pub exceptional_record_size: Option<Integer>,
137 #[rasn(tag(12))]
138 pub result: bool,
139 #[rasn(tag(110))]
140 pub implementation_id: Option<Utf8String>,
141 #[rasn(tag(111))]
142 pub implementation_name: Option<Utf8String>,
143 #[rasn(tag(112))]
144 pub implementation_version: Option<Utf8String>,
145 #[rasn(tag(11))]
146 pub user_information_field: Option<OctetString>,
147 pub other_info: Option<OctetString>,
148}
149
150#[derive(Debug, AsnType, Encode, Decode)]
151#[rasn(tag(22))] pub struct SearchRequest {
153 #[rasn(tag(2))]
154 pub reference_id: Option<OctetString>,
155
156 #[rasn(tag(13))]
157 pub small_set_upper_bound: Integer,
158
159 #[rasn(tag(14))]
160 pub large_set_lower_bound: Integer,
161
162 #[rasn(tag(15))]
163 pub medium_set_present_number: Integer,
164
165 #[rasn(tag(16))]
166 pub replace_indicator: bool,
167
168 #[rasn(tag(17))]
169 pub result_set_name: Utf8String,
170
171 #[rasn(tag(18))]
172 pub database_names: Vec<DatabaseName>,
173
174 #[rasn(tag(104))]
175 pub preferred_record_syntax: Option<ObjectIdentifier>,
176
177 #[rasn(tag(explicit(21)))]
179 pub query: Query,
180}
181
182#[derive(Debug, AsnType, Encode, Decode)]
183#[rasn(tag(23))]
184pub struct SearchResponse {
185 #[rasn(tag(context, 2))]
186 pub reference_id: Option<OctetString>,
187 #[rasn(tag(context, 23))]
188 pub result_count: Integer,
189 #[rasn(tag(context, 24))]
190 pub number_of_records_returned: Integer,
191 #[rasn(tag(context, 25))]
192 pub next_result_set_position: Integer,
193 #[rasn(tag(context, 22))]
194 pub search_status: bool,
195 #[rasn(tag(context, 26))]
196 pub result_set_status: Option<Integer>,
197 #[rasn(tag(context, 27))]
198 pub present_status: Option<PresentStatus>,
199 pub records: Option<Records>,
200 #[rasn(tag(context, 203))]
201 pub additional_search_info: Option<OctetString>,
202 pub other_info: Option<OctetString>,
203}
204
205#[derive(Debug, AsnType, Encode, Decode)]
206pub struct PresentRequest {
207 #[rasn(tag(context, 2))]
208 pub reference_id: Option<OctetString>,
209 #[rasn(tag(context, 31))]
210 pub result_set_id: Utf8String,
211 #[rasn(tag(context, 30))]
212 pub result_set_start_point: Integer,
213 #[rasn(tag(context, 29))]
214 pub number_of_records_requested: Integer,
215 #[rasn(tag(context, 212))]
216 pub additional_ranges: Option<Vec<Range>>,
217 pub record_composition: Option<RecordComposition>,
218 #[rasn(tag(context, 104))]
219 pub preferred_record_syntax: Option<ObjectIdentifier>,
220 #[rasn(tag(context, 204))]
221 pub max_segment_count: Option<Integer>,
222 #[rasn(tag(context, 206))]
223 pub max_record_size: Option<Integer>,
224 #[rasn(tag(context, 207))]
225 pub max_segment_size: Option<Integer>,
226 #[rasn(tag(context, 210))]
227 pub other_info: Option<OtherInformation>,
228}
229
230#[derive(Debug, AsnType, Encode, Decode)]
231pub struct OtherInformation {
232 #[rasn(tag(context, 1))]
233 pub category: Option<InfoCategory>,
234
235 pub information: OtherInformationChoice,
236}
237
238#[derive(AsnType, Encode, Decode, Debug)]
239pub struct InfoCategory {
240 #[rasn(tag(context, 1))]
241 pub category_type_id: Option<ObjectIdentifier>,
242
243 #[rasn(tag(context, 2))]
244 pub category_value: Integer,
245}
246
247#[derive(AsnType, Encode, Decode, Debug)]
248#[rasn(choice)]
249pub enum OtherInformationChoice {
250 #[rasn(tag(context, 2))]
251 CharacterInfo(Utf8String),
252
253 #[rasn(tag(context, 3))]
254 BinaryInfo(OctetString),
255
256 #[rasn(tag(context, 4))]
257 ExternallyDefinedInfo(External),
258
259 #[rasn(tag(context, 5))]
260 Oid(ObjectIdentifier),
261}
262
263#[derive(Debug, AsnType, Encode, Decode)]
267#[rasn(choice)]
268pub enum RecordComposition {
269 #[rasn(tag(explicit(context, 19)))]
270 Simple(ElementSetNames),
271 #[rasn(tag(explicit(context, 209)))]
272 Complex(CompSpec),
273}
274
275#[derive(Debug, AsnType, Encode, Decode)]
276#[rasn(choice)]
277pub enum ElementSetNames {
278 #[rasn(tag(context, 0))]
279 GenericElementSetName(Utf8String),
280 #[rasn(tag(context, 1))]
281 DatabaseSpecific(Vec<DbElementSetName>),
282}
283
284#[derive(Debug, AsnType, Encode, Decode)]
285pub struct DbElementSetName {
286 pub db_name: DatabaseName,
287 pub element_set_name: Utf8String,
288}
289
290#[derive(Debug, AsnType, Encode, Decode)]
291pub struct CompSpec {
292 #[rasn(tag(context, 1))]
293 pub select_alternative_syntax: bool,
294 #[rasn(tag(context, 2))]
295 pub generic: Option<Specification>,
296 #[rasn(tag(context, 3))]
297 pub db_specific: Option<Vec<DbSpecificSpec>>,
298 #[rasn(tag(context, 4))]
299 pub record_syntax: Option<Vec<ObjectIdentifier>>,
300}
301
302#[derive(Debug, AsnType, Encode, Decode)]
303pub struct DbSpecificSpec {
304 pub db: DatabaseName,
305 pub spec: Specification,
306}
307#[derive(Debug, AsnType, Encode, Decode)]
308pub struct Range {
309 #[rasn(tag(context, 0))]
310 pub starting_position: Integer,
311 #[rasn(tag(context, 1))]
312 pub number_of_records: Integer,
313}
314
315#[derive(Debug, AsnType, Encode, Decode)]
316#[rasn(tag(context, 25))]
317pub struct PresentResponse {
318 #[rasn(tag(context, 2))]
319 pub reference_id: Option<OctetString>,
320 #[rasn(tag(context, 24))]
321 pub number_of_records_returned: Integer, #[rasn(tag(context, 25))]
323 pub next_result_set_position: Integer, #[rasn(tag(context, 27))]
326 pub present_status: Option<PresentStatus>,
327 pub records: Option<Records>,
328 #[rasn(tag(context, 201))]
330 pub other_info: Option<OtherInformation>,
331}
332
333#[derive(Debug, AsnType, Encode, Decode)]
338pub struct DeleteResultSetRequest {
339 #[rasn(tag(context, 2))]
340 pub reference_id: Option<OctetString>,
341 #[rasn(tag(context, 32))]
342 pub delete_function: DeleteFunction,
343 pub result_set_list: Option<Vec<ResultSetId>>,
344 #[rasn(tag(context, 201))]
345 pub other_info: Option<OtherInformation>,
346}
347
348#[derive(Debug, AsnType, Encode, Decode, Clone, Copy, PartialEq, Eq)]
349#[rasn(enumerated)]
350pub enum DeleteFunction {
351 List = 0,
352 All = 1,
353}
354
355pub type ResultSetId = Utf8String;
356
357#[derive(Debug, AsnType, Encode, Decode)]
358#[rasn(tag(context, 27))]
359pub struct DeleteResultSetResponse {
360 #[rasn(tag(context, 2))]
361 pub reference_id: Option<OctetString>,
362 #[rasn(tag(context, 0))]
363 pub delete_operation_status: DeleteOperationStatus,
364 #[rasn(tag(context, 1))]
365 pub delete_list_statuses: Option<Vec<ListStatus>>,
366 #[rasn(tag(context, 34))]
367 pub number_not_deleted: Option<Integer>,
368 #[rasn(tag(context, 35))]
369 pub bulk_statuses: Option<Vec<ListStatus>>,
370 #[rasn(tag(context, 36))]
371 pub delete_message: Option<Utf8String>,
372 #[rasn(tag(context, 201))]
373 pub other_info: Option<OtherInformation>,
374}
375
376#[derive(Debug, AsnType, Encode, Decode, Clone, Copy, PartialEq, Eq)]
377#[rasn(enumerated)]
378pub enum DeleteOperationStatus {
379 Success = 0,
380 ResultSetDidNotExist = 1,
381 PreviouslyDeletedByTarget = 2,
382 SystemProblemAtTarget = 3,
383 AccessNotAllowed = 4,
384 ResourceControlAtOrigin = 5,
385 ResourceControlAtTarget = 6,
386 BulkDeleteNotSupported = 7,
387 NotAllRsltSetsDeletedOnBulkDlte = 8,
388 NotAllRequestedResultSetsDeleted = 9,
389 ResultSetInUse = 10,
390}
391
392#[derive(Debug, AsnType, Encode, Decode)]
393pub struct ListStatus {
394 pub id: ResultSetId,
395 pub status: DeleteOperationStatus,
396}
397
398#[derive(Debug, AsnType, Encode, Decode)]
403pub struct AccessControlRequest {
404 #[rasn(tag(context, 2))]
405 pub reference_id: Option<OctetString>,
406 pub security_challenge: AccessControlSecurityChallenge,
407 #[rasn(tag(context, 201))]
408 pub other_info: Option<OtherInformation>,
409}
410
411#[derive(Debug, AsnType, Encode, Decode)]
412#[rasn(choice)]
413pub enum AccessControlSecurityChallenge {
414 #[rasn(tag(context, 37))]
415 SimpleForm(OctetString),
416 #[rasn(tag(context, 0))]
417 ExternallyDefined(External),
418}
419
420#[derive(Debug, AsnType, Encode, Decode)]
421pub struct AccessControlResponse {
422 #[rasn(tag(context, 2))]
423 pub reference_id: Option<OctetString>,
424 pub security_challenge_response: Option<AccessControlSecurityChallengeResponse>,
425 #[rasn(tag(context, 223))]
426 pub diagnostic: Option<DiagRec>,
427 #[rasn(tag(context, 201))]
428 pub other_info: Option<OtherInformation>,
429}
430
431#[derive(Debug, AsnType, Encode, Decode)]
432#[rasn(choice)]
433pub enum AccessControlSecurityChallengeResponse {
434 #[rasn(tag(context, 38))]
435 SimpleForm(OctetString),
436 #[rasn(tag(context, 0))]
437 ExternallyDefined(External),
438}
439
440#[derive(Debug, AsnType, Encode, Decode)]
445pub struct ResourceControlRequest {
446 #[rasn(tag(context, 2))]
447 pub reference_id: Option<OctetString>,
448 #[rasn(tag(context, 39))]
449 pub suspended_flag: Option<bool>,
450 #[rasn(tag(context, 40))]
451 pub resource_report: Option<ResourceReport>,
452 #[rasn(tag(context, 41))]
453 pub partial_results_available: Option<PartialResultsAvailable>,
454 #[rasn(tag(context, 46))]
455 pub response_required: bool,
456 #[rasn(tag(context, 47))]
457 pub triggered_request_flag: Option<bool>,
458 #[rasn(tag(context, 201))]
459 pub other_info: Option<OtherInformation>,
460}
461
462#[derive(Debug, AsnType, Encode, Decode, Clone, Copy, PartialEq, Eq)]
463#[rasn(enumerated)]
464pub enum PartialResultsAvailable {
465 Subset = 1,
466 Interim = 2,
467 None = 3,
468}
469
470pub type ResourceReport = External;
471
472#[derive(Debug, AsnType, Encode, Decode)]
473pub struct ResourceControlResponse {
474 #[rasn(tag(context, 2))]
475 pub reference_id: Option<OctetString>,
476 #[rasn(tag(context, 44))]
477 pub continue_flag: bool,
478 #[rasn(tag(context, 45))]
479 pub result_set_wanted: Option<bool>,
480 #[rasn(tag(context, 201))]
481 pub other_info: Option<OtherInformation>,
482}
483
484#[derive(Debug, AsnType, Encode, Decode)]
485pub struct TriggerResourceControlRequest {
486 #[rasn(tag(context, 2))]
487 pub reference_id: Option<OctetString>,
488 #[rasn(tag(context, 42))]
489 pub requested_action: TriggerRequestedAction,
490 #[rasn(tag(context, 43))]
491 pub preferred_resource_report_format: Option<ObjectIdentifier>,
492 #[rasn(tag(context, 48))]
493 pub result_set_wanted: Option<bool>,
494 #[rasn(tag(context, 201))]
495 pub other_info: Option<OtherInformation>,
496}
497
498#[derive(Debug, AsnType, Encode, Decode, Clone, Copy, PartialEq, Eq)]
499#[rasn(enumerated)]
500pub enum TriggerRequestedAction {
501 ResourceReport = 1,
502 ResourceControl = 2,
503 Cancel = 3,
504}
505
506#[derive(Debug, AsnType, Encode, Decode)]
511pub struct ResourceReportRequest {
512 #[rasn(tag(context, 2))]
513 pub reference_id: Option<OctetString>,
514 #[rasn(tag(context, 49))]
515 pub op_id: Option<ReferenceId>,
516 #[rasn(tag(context, 43))]
517 pub preferred_resource_report_format: Option<ObjectIdentifier>,
518 #[rasn(tag(context, 201))]
519 pub other_info: Option<OtherInformation>,
520}
521
522pub type ReferenceId = OctetString;
523
524#[derive(Debug, AsnType, Encode, Decode)]
525pub struct ResourceReportResponse {
526 #[rasn(tag(context, 2))]
527 pub reference_id: Option<OctetString>,
528 #[rasn(tag(context, 50))]
529 pub resource_report_status: ResourceReportStatus,
530 #[rasn(tag(context, 40))]
531 pub resource_report: Option<ResourceReport>,
532 #[rasn(tag(context, 201))]
533 pub other_info: Option<OtherInformation>,
534}
535
536#[derive(Debug, AsnType, Encode, Decode, Clone, Copy, PartialEq, Eq)]
537#[rasn(enumerated)]
538pub enum ResourceReportStatus {
539 Success = 0,
540 Partial = 1,
541 FailureNoReport = 2,
542 FailureNoReportNoEstimate = 3,
543 FailureNoReportCannotDetermine = 4,
544 FailureNoReportDueToCondition = 5,
545 FailureReportNotSupported = 6,
546 FailureReportFormatNotSupported = 7,
547}
548
549#[derive(Debug, AsnType, Encode, Decode)]
554#[rasn(tag(35))]
555pub struct ScanRequest {
556 #[rasn(tag(context, 2))]
557 pub reference_id: Option<OctetString>,
558 #[rasn(tag(context, 3))]
559 pub database_names: Vec<DatabaseName>,
560 pub attribute_set: Option<ObjectIdentifier>,
561 pub terms_list_and_start_point: AttributesPlusTerm,
562 #[rasn(tag(context, 5))]
563 pub step_size: Option<Integer>,
564 #[rasn(tag(context, 6))]
565 pub number_of_terms_requested: Integer,
566 #[rasn(tag(context, 7))]
567 pub preferred_position_in_response: Option<Integer>,
568 #[rasn(tag(context, 201))]
569 pub other_info: Option<OtherInformation>,
570}
571
572#[derive(Debug, AsnType, Encode, Decode)]
573pub struct ScanResponse {
574 #[rasn(tag(context, 2))]
575 pub reference_id: Option<OctetString>,
576 #[rasn(tag(context, 3))]
577 pub step_size: Option<Integer>,
578 #[rasn(tag(context, 4))]
579 pub scan_status: ScanStatus,
580 #[rasn(tag(context, 5))]
581 pub number_of_entries_returned: Integer,
582 #[rasn(tag(context, 6))]
583 pub position_of_term: Option<Integer>,
584 #[rasn(tag(context, 7))]
585 pub entries: Option<ListEntries>,
586 #[rasn(tag(context, 8))]
587 pub attribute_set: Option<ObjectIdentifier>,
588 #[rasn(tag(context, 201))]
589 pub other_info: Option<OtherInformation>,
590}
591
592#[derive(Debug, AsnType, Encode, Decode, Clone, Copy, PartialEq, Eq)]
593#[rasn(enumerated)]
594pub enum ScanStatus {
595 Success = 0,
596 PartialBeginning = 1,
597 PartialEnd = 2,
598 PartialBoth = 3,
599 PartialEmpty = 4,
600 PartialEstimate = 5,
601 Failure = 6,
602}
603
604#[derive(Debug, AsnType, Encode, Decode)]
605pub struct ListEntries {
606 pub entries: Option<Vec<Entry>>,
607 #[rasn(tag(context, 2))]
608 pub nonsurrogate_diagnostics: Option<Vec<DiagRec>>,
609}
610
611#[derive(Debug, AsnType, Encode, Decode)]
612#[rasn(choice)]
613pub enum Entry {
614 #[rasn(tag(context, 1))]
615 TermInfo(TermInfo),
616 #[rasn(tag(context, 2))]
617 SurrogateDiagnostic(DiagRec),
618}
619
620#[derive(Debug, AsnType, Encode, Decode)]
621pub struct TermInfo {
622 pub term: Term,
623 #[rasn(tag(context, 1))]
624 pub display_term: Option<Utf8String>,
625 pub suggested_attributes: Option<AttributeList>,
626 #[rasn(tag(context, 2))]
627 pub alternative_term: Option<Vec<AttributesPlusTerm>>,
628 #[rasn(tag(context, 3))]
629 pub global_occurrences: Option<Integer>,
630 #[rasn(tag(context, 4))]
631 pub by_attributes: Option<OccurrenceByAttributes>,
632 #[rasn(tag(context, 201))]
633 pub other_term_info: Option<OtherInformation>,
634}
635
636#[derive(Debug, AsnType, Encode, Decode)]
637pub struct OccurrenceByAttributes {
638 pub occurrences: Vec<OccurrenceByAttributesElem>,
639}
640
641#[derive(Debug, AsnType, Encode, Decode)]
642pub struct OccurrenceByAttributesElem {
643 pub attributes: AttributeList,
644 pub occurrences: Option<OccurrencesValue>,
645}
646
647#[derive(Debug, AsnType, Encode, Decode)]
648#[rasn(choice)]
649pub enum OccurrencesValue {
650 #[rasn(tag(context, 2))]
651 Global(Integer),
652 #[rasn(tag(context, 3))]
653 ByDatabase(Vec<OccurrenceByDatabase>),
654}
655
656#[derive(Debug, AsnType, Encode, Decode)]
657pub struct OccurrenceByDatabase {
658 pub db: DatabaseName,
659 pub num: Option<Integer>,
660 #[rasn(tag(context, 201))]
661 pub other_db_info: Option<OtherInformation>,
662}
663
664#[derive(Debug, AsnType, Encode, Decode)]
669pub struct SortRequest {
670 #[rasn(tag(context, 2))]
671 pub reference_id: Option<OctetString>,
672 #[rasn(tag(context, 3))]
673 pub input_result_set_names: Vec<Utf8String>,
674 #[rasn(tag(context, 4))]
675 pub sorted_result_set_name: Utf8String,
676 #[rasn(tag(context, 5))]
677 pub sort_sequence: Vec<SortKeySpec>,
678 #[rasn(tag(context, 201))]
679 pub other_info: Option<OtherInformation>,
680}
681
682#[derive(Debug, AsnType, Encode, Decode)]
683pub struct SortKeySpec {
684 pub sort_element: SortElement,
685 #[rasn(tag(context, 1))]
686 pub sort_relation: SortRelation,
687 #[rasn(tag(context, 2))]
688 pub case_sensitivity: CaseSensitivity,
689 #[rasn(tag(context, 3))]
690 pub missing_value_action: Option<MissingValueAction>,
691}
692
693#[derive(Debug, AsnType, Encode, Decode)]
694#[rasn(choice)]
695pub enum SortElement {
696 #[rasn(tag(context, 1))]
697 Generic(SortKey),
698 #[rasn(tag(context, 2))]
699 DataBaseSpecific(Vec<SortDbSpecific>),
700}
701
702#[derive(Debug, AsnType, Encode, Decode)]
703pub struct SortDbSpecific {
704 pub database_name: DatabaseName,
705 pub db_sort: SortKey,
706}
707
708#[derive(Debug, AsnType, Encode, Decode)]
709#[rasn(choice)]
710pub enum SortKey {
711 #[rasn(tag(context, 0))]
712 SortField(Utf8String),
713 #[rasn(tag(context, 1))]
714 ElementSpec(Specification),
715 #[rasn(tag(context, 2))]
716 SortAttributes(SortAttributes),
717}
718
719#[derive(Debug, AsnType, Encode, Decode)]
720pub struct SortAttributes {
721 pub id: ObjectIdentifier,
722 pub list: AttributeList,
723}
724
725#[derive(Debug, AsnType, Encode, Decode)]
726pub struct Specification {
727 #[rasn(tag(context, 1))]
728 pub schema: Option<ObjectIdentifier>,
729 #[rasn(tag(context, 2))]
730 pub element_spec: Option<ElementSpec>,
731}
732
733#[derive(Debug, AsnType, Encode, Decode)]
734#[rasn(choice)]
735pub enum ElementSpec {
736 #[rasn(tag(context, 1))]
737 ElementSetName(Utf8String),
738 #[rasn(tag(context, 2))]
739 ExternalEspec(External),
740}
741
742#[derive(Debug, AsnType, Encode, Decode, Clone, Copy, PartialEq, Eq)]
743#[rasn(enumerated)]
744pub enum SortRelation {
745 Ascending = 0,
746 Descending = 1,
747 AscendingByFrequency = 3,
748 DescendingByFrequency = 4,
749}
750
751#[derive(Debug, AsnType, Encode, Decode, Clone, Copy, PartialEq, Eq)]
752#[rasn(enumerated)]
753pub enum CaseSensitivity {
754 CaseSensitive = 0,
755 CaseInsensitive = 1,
756}
757
758#[derive(Debug, AsnType, Encode, Decode)]
759#[rasn(choice)]
760pub enum MissingValueAction {
761 #[rasn(tag(context, 1))]
762 Abort(()),
763 #[rasn(tag(context, 2))]
764 Null(()),
765 #[rasn(tag(context, 3))]
766 MissingValueData(OctetString),
767}
768
769#[derive(Debug, AsnType, Encode, Decode)]
770pub struct SortResponse {
771 #[rasn(tag(context, 2))]
772 pub reference_id: Option<OctetString>,
773 #[rasn(tag(context, 3))]
774 pub sort_status: SortStatus,
775 #[rasn(tag(context, 4))]
776 pub result_set_status: Option<SortResultSetStatus>,
777 #[rasn(tag(context, 5))]
778 pub diagnostics: Option<Vec<DiagRec>>,
779 #[rasn(tag(context, 6))]
780 pub result_count: Option<Integer>,
781 #[rasn(tag(context, 201))]
782 pub other_info: Option<OtherInformation>,
783}
784
785#[derive(Debug, AsnType, Encode, Decode, Clone, Copy, PartialEq, Eq)]
786#[rasn(enumerated)]
787pub enum SortStatus {
788 Success = 0,
789 PartialResultsAvailable = 1,
790 Failure = 2,
791}
792
793#[derive(Debug, AsnType, Encode, Decode, Clone, Copy, PartialEq, Eq)]
794#[rasn(enumerated)]
795pub enum SortResultSetStatus {
796 Empty = 1,
797 Interim = 2,
798 Unchanged = 3,
799 None = 4,
800}
801
802#[derive(Debug, AsnType, Encode, Decode)]
807pub struct Segment {
808 #[rasn(tag(context, 2))]
809 pub reference_id: Option<OctetString>,
810 #[rasn(tag(context, 24))]
811 pub number_of_records_returned: Integer,
812 #[rasn(tag(context, 0))]
813 pub segment_records: Vec<NamePlusRecord>,
814 #[rasn(tag(context, 201))]
815 pub other_info: Option<OtherInformation>,
816}
817
818#[derive(Debug, AsnType, Encode, Decode)]
823pub struct ExtendedServicesRequest {
824 #[rasn(tag(context, 2))]
825 pub reference_id: Option<OctetString>,
826 #[rasn(tag(context, 3))]
827 pub function: ExtendedServicesFunction,
828 #[rasn(tag(context, 4))]
829 pub package_type: ObjectIdentifier,
830 #[rasn(tag(context, 5))]
831 pub package_name: Option<Utf8String>,
832 #[rasn(tag(context, 6))]
833 pub user_id: Option<Utf8String>,
834 #[rasn(tag(context, 7))]
835 pub retention_time: Option<IntUnit>,
836 #[rasn(tag(context, 8))]
837 pub permissions: Option<Permissions>,
838 #[rasn(tag(context, 9))]
839 pub description: Option<Utf8String>,
840 #[rasn(tag(context, 10))]
841 pub task_specific_parameters: Option<External>,
842 #[rasn(tag(context, 11))]
843 pub wait_action: WaitAction,
844 #[rasn(tag(context, 103))]
845 pub elements: Option<ElementSetName>,
846 #[rasn(tag(context, 201))]
847 pub other_info: Option<OtherInformation>,
848}
849
850#[derive(Debug, AsnType, Encode, Decode, Clone, Copy, PartialEq, Eq)]
851#[rasn(enumerated)]
852pub enum ExtendedServicesFunction {
853 Create = 1,
854 Delete = 2,
855 Modify = 3,
856}
857
858#[derive(Debug, AsnType, Encode, Decode, Clone, Copy, PartialEq, Eq)]
859#[rasn(enumerated)]
860pub enum WaitAction {
861 Wait = 1,
862 WaitIfPossible = 2,
863 DontWait = 3,
864 DontReturnPackage = 4,
865}
866
867pub type ElementSetName = Utf8String;
868
869#[derive(Debug, AsnType, Encode, Decode)]
870pub struct Permissions {
871 pub permissions: Vec<PermissionsElem>,
872}
873
874#[derive(Debug, AsnType, Encode, Decode)]
875pub struct PermissionsElem {
876 #[rasn(tag(context, 1))]
877 pub user_id: Utf8String,
878 #[rasn(tag(context, 2))]
879 pub allowed_functions: Vec<AllowedFunction>,
880}
881
882#[derive(Debug, AsnType, Encode, Decode, Clone, Copy, PartialEq, Eq)]
883#[rasn(enumerated)]
884pub enum AllowedFunction {
885 Delete = 1,
886 ModifyContents = 2,
887 ModifyPermissions = 3,
888 Present = 4,
889 Invoke = 5,
890}
891
892#[derive(Debug, AsnType, Encode, Decode)]
893pub struct ExtendedServicesResponse {
894 #[rasn(tag(context, 2))]
895 pub reference_id: Option<OctetString>,
896 #[rasn(tag(context, 3))]
897 pub operation_status: ExtendedServicesStatus,
898 #[rasn(tag(context, 4))]
899 pub diagnostics: Option<Vec<DiagRec>>,
900 #[rasn(tag(context, 5))]
901 pub task_package: Option<External>,
902 #[rasn(tag(context, 201))]
903 pub other_info: Option<OtherInformation>,
904}
905
906#[derive(Debug, AsnType, Encode, Decode, Clone, Copy, PartialEq, Eq)]
907#[rasn(enumerated)]
908pub enum ExtendedServicesStatus {
909 Done = 1,
910 Accepted = 2,
911 Failure = 3,
912}
913
914#[derive(Debug, AsnType, Encode, Decode)]
919pub struct Close {
920 #[rasn(tag(context, 2))]
921 pub reference_id: Option<OctetString>,
922 #[rasn(tag(context, 211))]
923 pub close_reason: CloseReason,
924 #[rasn(tag(context, 3))]
925 pub diagnostic_information: Option<Utf8String>,
926 #[rasn(tag(context, 4))]
927 pub resource_report_format: Option<ObjectIdentifier>,
928 #[rasn(tag(context, 5))]
929 pub resource_report: Option<ResourceReport>,
930 #[rasn(tag(context, 201))]
931 pub other_info: Option<OtherInformation>,
932}
933
934#[derive(Debug, AsnType, Encode, Decode, Clone, Copy, PartialEq, Eq)]
935#[rasn(enumerated)]
936pub enum CloseReason {
937 Finished = 0,
938 Shutdown = 1,
939 SystemProblem = 2,
940 CostLimit = 3,
941 Resources = 4,
942 SecurityViolation = 5,
943 ProtocolError = 6,
944 LackOfActivity = 7,
945 PeerAbort = 8,
946 Unspecified = 9,
947}
948
949#[derive(Debug, AsnType, Encode, Decode)]
954pub struct DuplicateDetectionRequest {
955 #[rasn(tag(context, 2))]
956 pub reference_id: Option<OctetString>,
957 #[rasn(tag(context, 3))]
958 pub input_result_set_ids: Vec<Utf8String>,
959 #[rasn(tag(context, 4))]
960 pub output_result_set_name: Utf8String,
961 #[rasn(tag(context, 5))]
962 pub applicable_portion: Option<ApplicablePortion>,
963 #[rasn(tag(context, 6))]
964 pub duplicate_detection_criteria: Option<Vec<DuplicateDetectionCriterion>>,
965 #[rasn(tag(context, 7))]
966 pub clustering: Option<bool>,
967 #[rasn(tag(context, 8))]
968 pub retention_criteria: Option<Vec<RetentionCriterion>>,
969 #[rasn(tag(context, 9))]
970 pub sorting_criteria: Option<Vec<SortCriterion>>,
971 #[rasn(tag(context, 201))]
972 pub other_info: Option<OtherInformation>,
973}
974
975#[derive(Debug, AsnType, Encode, Decode)]
976#[rasn(choice)]
977pub enum ApplicablePortion {
978 #[rasn(tag(context, 2))]
979 Full(()),
980 #[rasn(tag(context, 3))]
981 Fields(Vec<Utf8String>),
982}
983
984#[derive(Debug, AsnType, Encode, Decode)]
985#[rasn(choice)]
986pub enum DuplicateDetectionCriterion {
987 #[rasn(tag(context, 1))]
988 LevelOfMatch(Integer),
989 #[rasn(tag(context, 2))]
990 CaseSensitive(bool),
991 #[rasn(tag(context, 3))]
992 PunctuationSensitive(bool),
993 #[rasn(tag(context, 4))]
994 RegularExpression(External),
995 #[rasn(tag(context, 5))]
996 RsDuplicates(External),
997}
998
999#[derive(Debug, AsnType, Encode, Decode)]
1000#[rasn(choice)]
1001pub enum RetentionCriterion {
1002 #[rasn(tag(context, 1))]
1003 NumberOfEntries(Integer),
1004 #[rasn(tag(context, 2))]
1005 PercentOfEntries(Integer),
1006 #[rasn(tag(context, 3))]
1007 DuplicatesOnly(()),
1008 #[rasn(tag(context, 4))]
1009 DiscardRsDuplicates(()),
1010}
1011
1012#[derive(Debug, AsnType, Encode, Decode)]
1013#[rasn(choice)]
1014pub enum SortCriterion {
1015 #[rasn(tag(context, 1))]
1016 MostComprehensive(()),
1017 #[rasn(tag(context, 2))]
1018 LeastComprehensive(()),
1019 #[rasn(tag(context, 3))]
1020 MostRecent(()),
1021 #[rasn(tag(context, 4))]
1022 Oldest(()),
1023 #[rasn(tag(context, 5))]
1024 LeastCostPerRecord(()),
1025 #[rasn(tag(context, 6))]
1026 PreferredDatabases(Vec<DatabaseName>),
1027}
1028
1029#[derive(Debug, AsnType, Encode, Decode)]
1030pub struct DuplicateDetectionResponse {
1031 #[rasn(tag(context, 2))]
1032 pub reference_id: Option<OctetString>,
1033 #[rasn(tag(context, 3))]
1034 pub status: DuplicateDetectionStatus,
1035 #[rasn(tag(context, 4))]
1036 pub result_set_count: Option<Integer>,
1037 #[rasn(tag(context, 5))]
1038 pub diagnostics: Option<Vec<DiagRec>>,
1039 #[rasn(tag(context, 201))]
1040 pub other_info: Option<OtherInformation>,
1041}
1042
1043#[derive(Debug, AsnType, Encode, Decode, Clone, Copy, PartialEq, Eq)]
1044#[rasn(enumerated)]
1045pub enum DuplicateDetectionStatus {
1046 Success = 0,
1047 PartialSomeInputNotProcessed = 1,
1048 PartialSomeCriteriaNotApplied = 2,
1049 PartialBothProblems = 3,
1050 Failure = 4,
1051}
1052
1053#[derive(Debug, AsnType, Encode, Decode)]
1054#[rasn(choice)]
1055pub enum Records {
1056 #[rasn(tag(context, 28))]
1057 ResponseRecords(Vec<NamePlusRecord>),
1058 #[rasn(tag(context, 130))]
1059 NonSurrogateDiagnostic(DefaultDiagFormat),
1060 #[rasn(tag(context, 205))]
1061 MultipeNonSurDiagnostic(Vec<DiagRec>),
1062}
1063
1064#[derive(AsnType, Encode, Decode, Debug)]
1065#[rasn(choice)]
1066pub enum DiagRec {
1067 DefaultFormat(DefaultDiagFormat),
1068 ExternallDefined(External),
1069}
1070
1071#[derive(AsnType, Encode, Decode, Debug)]
1072pub struct DefaultDiagFormat {
1073 pub diagnostic_set_id: ObjectIdentifier,
1074 pub condition: Integer,
1075 pub addinfo: AddInfo,
1076}
1077
1078#[derive(AsnType, Encode, Decode, Debug)]
1079#[rasn(choice)]
1080pub enum AddInfo {
1081 V2Addinfo(VisibleString),
1082 V3Addinfo(Utf8String),
1083}
1084
1085#[derive(Debug, AsnType, Encode, Decode)]
1086pub struct NamePlusRecord {
1087 #[rasn(tag(context, 0))]
1088 pub name: Option<VisibleString>,
1089
1090 #[rasn(tag(explicit(context, 1)))] pub record: Record,
1092}
1093
1094#[derive(Debug, AsnType, Encode, Decode)]
1095#[rasn(choice)]
1096pub enum Record {
1097 #[rasn(tag(explicit(context, 1)))]
1098 RetrievalRecord(External),
1099 #[rasn(tag(context, 2))]
1100 SurrogateDiagnostic(DiagRec),
1101 #[rasn(tag(context, 3))]
1102 StartingFragment(FragmentSyntax),
1103 #[rasn(tag(context, 4))]
1104 IntermediateFragment(FragmentSyntax),
1105 #[rasn(tag(context, 5))]
1106 FinalFragment(FragmentSyntax),
1107}
1108
1109#[derive(Debug, AsnType, Encode, Decode, Clone)]
1110#[rasn(choice)]
1111pub enum FragmentSyntax {
1112 ExternallyTagged(External),
1113 NotExternallyTagged(OctetString),
1114}
1115
1116#[derive(Debug, AsnType, Encode, Decode, Clone)]
1117#[rasn(tag(universal, 8))]
1118pub struct External {
1119 pub direct_reference: Option<ObjectIdentifier>,
1120 pub indirect_reference: Option<Integer>,
1121 pub data_value_descriptor: Option<Utf8String>,
1122 pub encoding: ExternalEncoding,
1123}
1124
1125#[derive(Debug, AsnType, Encode, Decode, Clone)]
1126#[rasn(choice)]
1127pub enum ExternalEncoding {
1128 #[rasn(tag(context, 0))]
1129 SingleASN1Type(Any),
1130 #[rasn(tag(context, 1))]
1131 OctetAligned(OctetString),
1132 #[rasn(tag(context, 2))]
1133 Arbitrary(BitString),
1134}
1135
1136#[derive(Debug, AsnType, Encode, Decode, Clone, Copy, PartialEq, Eq)]
1137#[rasn(enumerated)]
1138pub enum PresentStatus {
1139 Success = 0,
1140 Partial1 = 1,
1141 Partial2 = 2,
1142 Partial3 = 3,
1143 Partial4 = 4,
1144 Failure = 5,
1145}
1146
1147#[derive(Debug, AsnType, Encode, Decode)]
1148#[rasn(choice)]
1149pub enum IdAuthentication {
1150 #[rasn(tag(universal, 26))]
1151 Open(VisibleString),
1152 #[rasn(tag(context, 1))]
1153 IdPass(IdPass),
1154}
1155
1156#[derive(Debug, AsnType, Encode, Decode)]
1157pub struct IdPass {
1158 #[rasn(tag(context, 0))]
1159 pub id: Utf8String,
1160 #[rasn(tag(context, 1))]
1161 pub password: Utf8String,
1162}
1163
1164#[derive(Debug, AsnType, Encode, Decode)]
1165#[rasn(choice)]
1166pub enum Query {
1167 #[rasn(tag(context, 1))]
1169 Type1(RpnQuery),
1170
1171 #[rasn(tag(context, 2))]
1172 Type2(RpnQuery),
1173
1174 #[rasn(tag(context, 100))]
1176 Type100(OctetString),
1177
1178 #[rasn(tag(context, 101))]
1181 Type101(RpnQuery),
1182
1183 #[rasn(tag(context, 102))]
1185 Type102(OctetString),
1186}
1187
1188#[derive(Debug, AsnType, Encode, Decode)]
1189pub struct RpnQuery {
1190 pub attribute_set: ObjectIdentifier,
1191 pub rpn: RpnStructure,
1192}
1193
1194#[derive(Debug, AsnType, Encode, Decode, Clone)]
1195#[rasn(choice)]
1196pub enum RpnStructure {
1197 #[rasn(tag(context, 0))]
1198 Op(Operand),
1199 #[rasn(tag(context, 1))]
1200 RpnRpnOperator(RpnRpnOperator),
1201}
1202
1203#[derive(Debug, AsnType, Encode, Decode, Clone)]
1204pub struct RpnRpnOperator {
1205 pub rpn1: Box<RpnStructure>, pub rpn2: Box<RpnStructure>,
1207 pub op: Operator,
1208}
1209
1210#[derive(Debug, AsnType, Encode, Decode, Clone)]
1211#[rasn(choice)]
1212pub enum Operator {
1213 #[rasn(tag(context, 0))]
1214 And(()),
1215 #[rasn(tag(context, 1))]
1216 Or(()),
1217 #[rasn(tag(context, 2))]
1218 AndNot(()),
1219}
1220
1221#[derive(Debug, AsnType, Encode, Decode, Clone)]
1222#[rasn(choice)]
1223pub enum Operand {
1224 #[rasn(tag(context, 102))]
1225 AttributesPlusTerm(AttributesPlusTerm),
1226 #[rasn(tag(context, 33))]
1227 ResultSet(Utf8String),
1228 #[rasn(tag(context, 214))]
1229 ResultAttr(ResultSetPlusAttributes),
1230}
1231
1232#[derive(Debug, AsnType, Encode, Decode, Clone)]
1233pub struct ResultSetPlusAttributes {
1234 pub result_set: Utf8String,
1235 pub attributes: AttributeList,
1236}
1237
1238#[derive(Debug, AsnType, Encode, Decode, Clone)]
1239#[rasn(tag(context, 102))] pub struct AttributesPlusTerm {
1241 #[rasn(tag(context, 44))]
1242 pub attributes: Vec<AttributeElement>,
1243 pub term: Term,
1244}
1245
1246#[derive(Debug, AsnType, Encode, Decode, Clone)]
1247pub struct AttributeList {
1248 pub elements: Vec<AttributeElement>,
1249}
1250
1251#[derive(Debug, AsnType, Encode, Decode, Clone)]
1252pub struct AttributeElement {
1253 #[rasn(tag(context, 1))]
1254 pub attribute_set: Option<ObjectIdentifier>,
1255 #[rasn(tag(context, 120))]
1256 pub attribute_type: Integer,
1257 pub attribute_value: AttributeValue,
1258}
1259
1260#[derive(Debug, AsnType, Encode, Decode, Clone)]
1261#[rasn(choice)]
1262pub enum AttributeValue {
1263 #[rasn(tag(context, 121))]
1264 Numeric(Integer),
1265}
1266
1267#[derive(Debug, AsnType, Encode, Decode, Clone)]
1268#[rasn(choice)]
1269pub enum Term {
1270 #[rasn(tag(45))]
1271 General(OctetString),
1272
1273 #[rasn(tag(context, 215))]
1274 Numeric(Integer),
1275 #[rasn(tag(context, 216))]
1276 CharacterString(Utf8String),
1277 #[rasn(tag(context, 217))]
1278 Oid(ObjectIdentifier),
1279 #[rasn(tag(context, 218))]
1280 DateTime(GeneralizedTime),
1281 #[rasn(tag(context, 219))]
1282 External(External),
1283 #[rasn(tag(context, 220))]
1284 IntegerAndUnit(IntUnit),
1285 #[rasn(tag(context, 221))]
1286 Null(()),
1287}
1288
1289#[derive(Debug, AsnType, Encode, Decode, Clone)]
1290#[rasn(choice)]
1291pub enum IntUnit {
1292 #[rasn(tag(context, 1))]
1293 Value(Integer),
1294 #[rasn(tag(context, 2))]
1295 Unit(Unit),
1296}
1297
1298#[derive(Debug, AsnType, Encode, Decode, Clone)]
1299
1300pub struct Unit {
1301 #[rasn(tag(context, 1))]
1302 pub unit_system: Option<Utf8String>,
1303 #[rasn(tag(context, 2))]
1304 pub unit_type: Option<StringOrNumeric>,
1305 #[rasn(tag(context, 3))]
1306 pub unit: Option<StringOrNumeric>,
1307}
1308
1309#[derive(Debug, AsnType, Encode, Decode, Clone)]
1310#[rasn(choice)]
1311pub enum StringOrNumeric {
1312 #[rasn(tag(context, 1))]
1313 String(Utf8String),
1314 #[rasn(tag(context, 2))]
1315 Numeric(Integer),
1316}
1317
1318pub fn bib1_attribute_set() -> Result<ObjectIdentifier> {
1320 ObjectIdentifier::new(vec![1, 2, 840, 10003, 3, 1]).ok_or_else(|| Error::InvalidOid("failed to construct BIB-1 attribute set OID".into()))
1321}
1322
1323pub fn record_syntax_usmarc() -> Result<ObjectIdentifier> {
1325 ObjectIdentifier::new(vec![1, 2, 840, 10003, 5, 10]).ok_or_else(|| Error::InvalidOid("failed to construct USMARC record syntax OID".into()))
1326}
1327
1328pub fn make_init_request(auth: Option<&Credentials>) -> Result<InitRequest> {
1334 let mut protocol_version = BitString::with_capacity(16);
1336 protocol_version.push(true); protocol_version.push(true); protocol_version.push(true); for _ in 3..16 {
1340 protocol_version.push(false);
1341 }
1342
1343 let mut options = BitString::with_capacity(32);
1345 options.push(true); options.push(true); for _ in 2..32 {
1348 options.push(false);
1349 }
1350
1351 let id_authentication = match auth {
1352 None => None,
1353 Some(c) => {
1354 let combined = format!("{}/{}", c.username, c.password);
1356 let vs = VisibleString::from_iso646_bytes(combined.as_bytes()).map_err(|e| Error::InvalidVisibleString(e.to_string()))?;
1357 Some(IdAuthentication::Open(vs))
1358 }
1359 };
1360
1361 Ok(InitRequest {
1362 reference_id: None,
1363 protocol_version,
1364 options,
1365 preferred_message_size: 0x04000000i64.into(),
1366 exceptional_record_size: 0x04000000i64.into(),
1367 id_authentication,
1368 implementation_id: Some(Utf8String::from("81")),
1369 implementation_name: Some(Utf8String::from("YAZ")),
1370 implementation_version: Some(Utf8String::from("5.34.4 b42e25e840666ea3422c3bd5cb566b07f78a99cd")),
1371 user_information_field: None,
1372 other_info: None,
1373 })
1374}
1375
1376pub fn make_type1_query(attribute_type: i64, term: &str) -> Result<Query> {
1378 let attr = AttributeElement {
1379 attribute_set: Some(bib1_attribute_set()?),
1380 attribute_type: attribute_type.into(),
1381 attribute_value: AttributeValue::Numeric(1.into()),
1382 };
1383
1384 let rpn = RpnQuery {
1385 attribute_set: bib1_attribute_set()?,
1386 rpn: RpnStructure::Op(Operand::AttributesPlusTerm(AttributesPlusTerm {
1387 attributes: vec![attr],
1388
1389 term: Term::General(OctetString::from(term.as_bytes().to_vec())),
1390 })),
1391 };
1392
1393 Ok(Query::Type1(rpn))
1394}
1395
1396pub fn make_search_request(databases: &[String], result_set: &str, query: Query) -> Result<SearchRequest> {
1398 let database_names = databases
1399 .iter()
1400 .cloned()
1401 .map(|s| {
1402 let vs = VisibleString::from_iso646_bytes(s.as_bytes()).map_err(|e| Error::InvalidVisibleString(e.to_string()))?;
1403 Ok(DatabaseName::General(vs))
1404 })
1405 .collect::<Result<Vec<_>>>()?;
1406
1407 Ok(SearchRequest {
1408 reference_id: None,
1409 database_names,
1410 small_set_upper_bound: 0.into(),
1411 large_set_lower_bound: 1.into(),
1412 medium_set_present_number: 0.into(),
1413 replace_indicator: true,
1414 result_set_name: Utf8String::from(result_set),
1415 preferred_record_syntax: None,
1416 query,
1417 })
1418}
1419
1420pub fn make_present_request(result_set: &str, start: i64, count: i64) -> Result<PresentRequest> {
1422 Ok(PresentRequest {
1423 reference_id: None,
1424 result_set_id: Utf8String::from(result_set),
1425 result_set_start_point: start.into(),
1426 number_of_records_requested: count.into(),
1427 preferred_record_syntax: Some(record_syntax_usmarc()?),
1428 other_info: None,
1429 additional_ranges: None,
1430 record_composition: None,
1431 max_segment_count: None,
1432 max_record_size: None,
1433 max_segment_size: None,
1434 })
1435}
1436
1437pub fn make_delete_result_set_request(result_sets: &[&str]) -> DeleteResultSetRequest {
1439 DeleteResultSetRequest {
1440 reference_id: None,
1441 delete_function: DeleteFunction::List,
1442 result_set_list: Some(result_sets.iter().map(|s| Utf8String::from(*s)).collect()),
1443 other_info: None,
1444 }
1445}
1446
1447pub fn make_delete_all_result_sets_request() -> DeleteResultSetRequest {
1449 DeleteResultSetRequest {
1450 reference_id: None,
1451 delete_function: DeleteFunction::All,
1452 result_set_list: None,
1453 other_info: None,
1454 }
1455}
1456
1457pub fn make_scan_request(databases: &[String], term: &str, attribute_type: i64, step_size: Option<i64>, number_of_terms: i64, preferred_position: Option<i64>) -> Result<ScanRequest> {
1459 let database_names = databases
1460 .iter()
1461 .cloned()
1462 .map(|s| {
1463 let vs = VisibleString::from_iso646_bytes(s.as_bytes()).map_err(|e| Error::InvalidVisibleString(e.to_string()))?;
1464 Ok(DatabaseName::General(vs))
1465 })
1466 .collect::<Result<Vec<_>>>()?;
1467
1468 let attr = AttributeElement {
1469 attribute_set: Some(bib1_attribute_set()?),
1470 attribute_type: attribute_type.into(),
1471 attribute_value: AttributeValue::Numeric(1.into()),
1472 };
1473
1474 Ok(ScanRequest {
1475 reference_id: None,
1476 database_names,
1477 attribute_set: Some(bib1_attribute_set()?),
1478 terms_list_and_start_point: AttributesPlusTerm {
1479 attributes: vec![attr],
1480 term: Term::General(OctetString::from(term.as_bytes().to_vec())),
1481 },
1482 step_size: step_size.map(|s| s.into()),
1483 number_of_terms_requested: number_of_terms.into(),
1484 preferred_position_in_response: preferred_position.map(|p| p.into()),
1485 other_info: None,
1486 })
1487}
1488
1489pub fn make_sort_request(input_result_sets: &[&str], output_result_set: &str, sort_keys: Vec<SortKeySpec>) -> SortRequest {
1491 SortRequest {
1492 reference_id: None,
1493 input_result_set_names: input_result_sets.iter().map(|s| Utf8String::from(*s)).collect(),
1494 sorted_result_set_name: Utf8String::from(output_result_set),
1495 sort_sequence: sort_keys,
1496 other_info: None,
1497 }
1498}
1499
1500pub fn make_sort_key_by_field(field_name: &str, ascending: bool, case_sensitive: bool) -> SortKeySpec {
1502 SortKeySpec {
1503 sort_element: SortElement::Generic(SortKey::SortField(Utf8String::from(field_name))),
1504 sort_relation: if ascending { SortRelation::Ascending } else { SortRelation::Descending },
1505 case_sensitivity: if case_sensitive { CaseSensitivity::CaseSensitive } else { CaseSensitivity::CaseInsensitive },
1506 missing_value_action: None,
1507 }
1508}
1509
1510pub fn make_close_request(reason: CloseReason, diagnostic_info: Option<&str>) -> Close {
1512 Close {
1513 reference_id: None,
1514 close_reason: reason,
1515 diagnostic_information: diagnostic_info.map(|s| Utf8String::from(s)),
1516 resource_report_format: None,
1517 resource_report: None,
1518 other_info: None,
1519 }
1520}
1521
1522pub fn make_extended_services_request(
1524 function: ExtendedServicesFunction,
1525 package_type: ObjectIdentifier,
1526 package_name: Option<&str>,
1527 task_specific_parameters: Option<External>,
1528 wait_action: WaitAction,
1529) -> ExtendedServicesRequest {
1530 ExtendedServicesRequest {
1531 reference_id: None,
1532 function,
1533 package_type,
1534 package_name: package_name.map(|s| Utf8String::from(s)),
1535 user_id: None,
1536 retention_time: None,
1537 permissions: None,
1538 description: None,
1539 task_specific_parameters,
1540 wait_action,
1541 elements: None,
1542 other_info: None,
1543 }
1544}
1545
1546pub fn make_duplicate_detection_request(input_result_sets: &[&str], output_result_set: &str, clustering: bool) -> DuplicateDetectionRequest {
1548 DuplicateDetectionRequest {
1549 reference_id: None,
1550 input_result_set_ids: input_result_sets.iter().map(|s| Utf8String::from(*s)).collect(),
1551 output_result_set_name: Utf8String::from(output_result_set),
1552 applicable_portion: None,
1553 duplicate_detection_criteria: None,
1554 clustering: Some(clustering),
1555 retention_criteria: None,
1556 sorting_criteria: None,
1557 other_info: None,
1558 }
1559}
1560
1561pub fn make_resource_control_response(continue_flag: bool, result_set_wanted: Option<bool>) -> ResourceControlResponse {
1563 ResourceControlResponse {
1564 reference_id: None,
1565 continue_flag,
1566 result_set_wanted,
1567 other_info: None,
1568 }
1569}
1570
1571pub fn make_access_control_response(response: &[u8]) -> AccessControlResponse {
1573 AccessControlResponse {
1574 reference_id: None,
1575 security_challenge_response: Some(AccessControlSecurityChallengeResponse::SimpleForm(OctetString::from(response.to_vec()))),
1576 diagnostic: None,
1577 other_info: None,
1578 }
1579}
1580
1581pub fn make_trigger_resource_control_request(action: TriggerRequestedAction, result_set_wanted: Option<bool>) -> TriggerResourceControlRequest {
1583 TriggerResourceControlRequest {
1584 reference_id: None,
1585 requested_action: action,
1586 preferred_resource_report_format: None,
1587 result_set_wanted,
1588 other_info: None,
1589 }
1590}
1591
1592pub fn make_resource_report_request(op_id: Option<&[u8]>, preferred_format: Option<ObjectIdentifier>) -> ResourceReportRequest {
1594 ResourceReportRequest {
1595 reference_id: None,
1596 op_id: op_id.map(|b| OctetString::from(b.to_vec())),
1597 preferred_resource_report_format: preferred_format,
1598 other_info: None,
1599 }
1600}
1601
1602pub fn extract_marc_records(resp: &PresentResponse) -> Result<Vec<Vec<u8>>> {
1607 let mut out = Vec::new();
1608
1609 if let Some(Records::ResponseRecords(records)) = &resp.records {
1610 for rec in records {
1611 match &rec.record {
1612 Record::RetrievalRecord(external) => match &external.encoding {
1613 ExternalEncoding::OctetAligned(bytes) => {
1614 out.push(bytes.to_vec());
1615 }
1616 ExternalEncoding::SingleASN1Type(any) => {
1617 out.push(any.as_bytes().to_vec());
1618 }
1619 other => {
1620 return Err(Error::Protocol(format!("unsupported record encoding: {other:?}")));
1621 }
1622 },
1623 Record::SurrogateDiagnostic(diag) => {
1624 return Err(Error::Protocol(format!("surrogate diagnostic in record: {diag:?}")));
1625 }
1626 Record::StartingFragment(f) => {
1627 return Err(Error::Protocol(format!("fragmented record not supported (starting fragment): {f:?}")));
1628 }
1629 Record::IntermediateFragment(f) => {
1630 return Err(Error::Protocol(format!("fragmented record not supported (intermediate fragment): {f:?}")));
1631 }
1632 Record::FinalFragment(f) => {
1633 return Err(Error::Protocol(format!("fragmented record not supported (final fragment): {f:?}")));
1634 }
1635 }
1636 }
1637 return Ok(out);
1638 }
1639
1640 match &resp.records {
1641 None => Err(Error::Protocol("present response contains no records".into())),
1642 Some(Records::NonSurrogateDiagnostic(diag)) => Err(Error::Protocol(format!("present response diagnostic: {diag:?}"))),
1643 Some(Records::MultipeNonSurDiagnostic(diags)) => Err(Error::Protocol(format!("present response diagnostics: {diags:?}"))),
1644 Some(other) => Err(Error::Protocol(format!("unexpected records variant in present response: {other:?}"))),
1645 }
1646}