Mercurial > crates > nonstick
annotate src/pam_ffi/response.rs @ 73:ac6881304c78
Do conversations, along with way too much stuff.
This implements conversations, along with all the memory management
brouhaha that goes along with it. The conversation now lives directly
on the handle rather than being a thing you have to get from it
and then call manually. It Turns Out this makes things a lot easier!
I guess we reorganized things again. For the last time. For real.
I promise.
This all passes ASAN, so it seems Pretty Good!
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Thu, 05 Jun 2025 03:41:38 -0400 |
parents | 47eb242a4f88 |
children |
rev | line source |
---|---|
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
1 //! Types used when dealing with PAM conversations. |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
2 |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
3 use crate::conv::BinaryData; |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
4 use crate::pam_ffi::memory; |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
5 use crate::pam_ffi::memory::{CBinaryData, Immovable, NulError, TooBigError}; |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
6 use crate::Response; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
7 use std::ffi::{c_int, c_void, CStr}; |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
8 use std::ops::{Deref, DerefMut}; |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
9 use std::result::Result as StdResult; |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
10 use std::str::Utf8Error; |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
11 use std::{iter, mem, ptr, slice}; |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
12 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
13 #[repr(transparent)] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
14 #[derive(Debug)] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
15 pub struct RawTextResponse(RawResponse); |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
16 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
17 impl RawTextResponse { |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
18 /// Interprets the provided `RawResponse` as a text response. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
19 /// |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
20 /// # Safety |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
21 /// |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
22 /// It's up to you to provide a response that is a `RawTextResponse`. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
23 pub unsafe fn upcast(from: &mut RawResponse) -> &mut Self { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
24 // SAFETY: We're provided a valid reference. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
25 &mut *(from as *mut RawResponse).cast::<Self>() |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
26 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
27 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
28 /// Fills in the provided `RawResponse` with the given text. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
29 /// |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
30 /// You are responsible for calling [`free`](Self::free_contents) |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
31 /// on the pointer you get back when you're done with it. |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
32 pub fn fill(dest: &mut RawResponse, text: impl AsRef<str>) -> StdResult<&mut Self, NulError> { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
33 dest.data = memory::malloc_str(text)?.cast(); |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
34 // SAFETY: We just filled this in so we know it's a text response. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
35 Ok(unsafe { Self::upcast(dest) }) |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
36 } |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
37 |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
38 /// Gets the string stored in this response. |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
39 pub fn contents(&self) -> StdResult<&str, Utf8Error> { |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
40 if self.0.data.is_null() { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
41 Ok("") |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
42 } else { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
43 // SAFETY: This data is either passed from PAM (so we are forced to |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
44 // trust it) or was created by us in TextResponseInner::alloc. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
45 // In either case, it's going to be a valid null-terminated string. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
46 unsafe { CStr::from_ptr(self.0.data.cast()) }.to_str() |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
47 } |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
48 } |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
49 |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
50 /// Releases memory owned by this response. |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
51 pub fn free_contents(&mut self) { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
52 // SAFETY: We know we own this data. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
53 // After we're done, it will be null. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
54 unsafe { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
55 memory::zero_c_string(self.0.data); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
56 libc::free(self.0.data); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
57 self.0.data = ptr::null_mut() |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
58 } |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
59 } |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
60 } |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
61 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
62 /// A [`RawResponse`] with [`CBinaryData`] in it. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
63 #[repr(transparent)] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
64 #[derive(Debug)] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
65 pub struct RawBinaryResponse(RawResponse); |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
66 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
67 impl RawBinaryResponse { |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
68 /// Interprets the provided `RawResponse` as a binary response. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
69 /// |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
70 /// # Safety |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
71 /// |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
72 /// It's up to you to provide a response that is a `RawBinaryResponse`. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
73 pub unsafe fn upcast(from: &mut RawResponse) -> &mut Self { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
74 // SAFETY: We're provided a valid reference. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
75 &mut *(from as *mut RawResponse).cast::<Self>() |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
76 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
77 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
78 /// Fills in a `RawResponse` with the provided binary data. |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
79 /// |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
80 /// The `data_type` is a tag you can use for whatever. |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
81 /// It is passed through PAM unchanged. |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
82 /// |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
83 /// The referenced data is copied to the C heap. We do not take ownership. |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
84 /// You are responsible for calling [`free`](Self::free_contents) |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
85 /// on the pointer you get back when you're done with it. |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
86 pub fn fill<'a>( |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
87 dest: &'a mut RawResponse, |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
88 data: &[u8], |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
89 data_type: u8, |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
90 ) -> StdResult<&'a mut Self, TooBigError> { |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
91 dest.data = CBinaryData::alloc(data, data_type)?.cast(); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
92 // SAFETY: We just filled this in, so we know it's binary. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
93 Ok(unsafe { Self::upcast(dest) }) |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
94 } |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
95 |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
96 /// Gets the binary data in this response. |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
97 pub fn data(&self) -> &[u8] { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
98 self.contents().map(CBinaryData::contents).unwrap_or(&[]) |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
99 } |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
100 |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
101 /// Gets the `data_type` tag that was embedded with the message. |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
102 pub fn data_type(&self) -> u8 { |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
103 self.contents().map(CBinaryData::data_type).unwrap_or(0) |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
104 } |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
105 |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
106 fn contents(&self) -> Option<&CBinaryData> { |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
107 // SAFETY: This was either something we got from PAM (in which case |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
108 // we trust it), or something that was created with |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
109 // BinaryResponseInner::alloc. In both cases, it points to valid data. |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
110 unsafe { self.0.data.cast::<CBinaryData>().as_ref() } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
111 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
112 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
113 pub fn to_owned(&self) -> BinaryData { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
114 BinaryData::new(self.data().into(), self.data_type()) |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
115 } |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
116 |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
117 /// Releases memory owned by this response. |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
118 pub fn free_contents(&mut self) { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
119 // SAFETY: We know that our data pointer is either valid or null. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
120 // Once we're done, it's null and the response is safe. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
121 unsafe { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
122 let data_ref = self.0.data.cast::<CBinaryData>().as_mut(); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
123 if let Some(d) = data_ref { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
124 d.zero_contents() |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
125 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
126 libc::free(self.0.data); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
127 self.0.data = ptr::null_mut() |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
128 } |
70
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
129 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
130 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
131 |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
132 /// Generic version of response data. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
133 /// |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
134 /// This has the same structure as [`RawBinaryResponse`] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
135 /// and [`RawTextResponse`]. |
70
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
136 #[repr(C)] |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
137 #[derive(Debug)] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
138 pub struct RawResponse { |
70
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
139 /// Pointer to the data returned in a response. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
140 /// For most responses, this will be a [`CStr`], but for responses to |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
141 /// [`MessageStyle::BinaryPrompt`]s, this will be [`CBinaryData`] |
70
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
142 /// (a Linux-PAM extension). |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
143 data: *mut c_void, |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
144 /// Unused. |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
145 return_code: c_int, |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
146 _marker: Immovable, |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
147 } |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
148 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
149 /// A contiguous block of responses. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
150 #[derive(Debug)] |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
151 pub struct OwnedResponses { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
152 base: *mut RawResponse, |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
153 count: usize, |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
154 } |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
155 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
156 impl OwnedResponses { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
157 /// Allocates an owned list of responses on the C heap. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
158 fn alloc(count: usize) -> Self { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
159 OwnedResponses { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
160 // SAFETY: We are doing allocation here. |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
161 base: unsafe { libc::calloc(count, size_of::<RawResponse>()) }.cast(), |
72 | 162 count, |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
163 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
164 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
165 |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
166 pub fn build(value: &[Response]) -> StdResult<Self, FillError> { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
167 let mut outputs = OwnedResponses::alloc(value.len()); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
168 // If we fail in here after allocating OwnedResponses, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
169 // we still free all memory, even though we don't zero it first. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
170 // This is an acceptable level of risk. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
171 for (input, output) in iter::zip(value.iter(), outputs.iter_mut()) { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
172 match input { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
173 Response::NoResponse => { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
174 RawTextResponse::fill(output, "")?; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
175 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
176 Response::Text(data) => { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
177 RawTextResponse::fill(output, data)?; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
178 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
179 Response::MaskedText(data) => { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
180 RawTextResponse::fill(output, data.unsecure())?; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
181 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
182 Response::Binary(data) => { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
183 RawBinaryResponse::fill(output, data.data(), data.data_type())?; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
184 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
185 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
186 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
187 Ok(outputs) |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
188 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
189 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
190 /// Converts this into a `*RawResponse` for passing to PAM. |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
191 /// |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
192 /// The pointer "owns" its own data (i.e., this will not be dropped). |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
193 pub fn into_ptr(self) -> *mut RawResponse { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
194 let ret = self.base; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
195 mem::forget(self); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
196 ret |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
197 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
198 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
199 /// Takes ownership of a list of responses allocated on the C heap. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
200 /// |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
201 /// # Safety |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
202 /// |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
203 /// It's up to you to make sure you pass a valid pointer. |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
204 pub unsafe fn from_c_heap(base: *mut RawResponse, count: usize) -> Self { |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
205 OwnedResponses { base, count } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
206 } |
66
a674799a5cd3
Make `PamHandle` and `PamModuleHandle` traits.
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
207 } |
60
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
208 |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
209 #[derive(Debug, thiserror::Error)] |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
210 #[error("error converting responses: {0}")] |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
211 pub enum FillError { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
212 NulError(#[from] NulError), |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
213 TooBigError(#[from] TooBigError), |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
214 } |
60
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
215 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
216 impl Deref for OwnedResponses { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
217 type Target = [RawResponse]; |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
218 fn deref(&self) -> &Self::Target { |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
219 // SAFETY: This is the memory we manage ourselves. |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
220 unsafe { slice::from_raw_parts(self.base, self.count) } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
221 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
222 } |
60
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
223 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
224 impl DerefMut for OwnedResponses { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
225 fn deref_mut(&mut self) -> &mut Self::Target { |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
226 // SAFETY: This is the memory we manage ourselves. |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
227 unsafe { slice::from_raw_parts_mut(self.base, self.count) } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
228 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
229 } |
66
a674799a5cd3
Make `PamHandle` and `PamModuleHandle` traits.
Paul Fisher <paul@pfish.zone>
parents:
64
diff
changeset
|
230 |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
231 impl Drop for OwnedResponses { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
232 fn drop(&mut self) { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
233 // SAFETY: We allocated this ourselves, or it was provided to us by PAM. |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
234 unsafe { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
235 for resp in self.iter_mut() { |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
236 libc::free(resp.data) |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
237 } |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
238 libc::free(self.base.cast()) |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
239 } |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
240 } |
60
05cc2c27334f
The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
241 } |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
242 |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
243 #[cfg(test)] |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
244 mod tests { |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
245 use super::{BinaryData, OwnedResponses, RawBinaryResponse, RawTextResponse, Response}; |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
246 |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
247 #[test] |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
248 fn test_round_trip() { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
249 let responses = [ |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
250 Response::Binary(BinaryData::new(vec![1, 2, 3], 99)), |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
251 Response::Text("whats going on".to_owned()), |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
252 Response::MaskedText("well then".into()), |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
253 Response::NoResponse, |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
254 Response::Text("bogus".to_owned()), |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
255 ]; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
256 let sent = OwnedResponses::build(&responses).unwrap(); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
257 let heap_resps = sent.into_ptr(); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
258 let mut received = unsafe { OwnedResponses::from_c_heap(heap_resps, 5) }; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
259 |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
260 let assert_text = |want, raw| { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
261 let up = unsafe { RawTextResponse::upcast(raw) }; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
262 assert_eq!(want, up.contents().unwrap()); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
263 up.free_contents(); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
264 assert_eq!("", up.contents().unwrap()); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
265 }; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
266 let assert_bin = |want_data: &[u8], want_type, raw| { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
267 let up = unsafe { RawBinaryResponse::upcast(raw) }; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
268 assert_eq!(want_data, up.data()); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
269 assert_eq!(want_type, up.data_type()); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
270 up.free_contents(); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
271 let empty: [u8; 0] = []; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
272 assert_eq!(&empty, up.data()); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
273 assert_eq!(0, up.data_type()); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
274 }; |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
275 if let [zero, one, two, three, four] = &mut received[..] { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
276 assert_bin(&[1, 2, 3], 99, zero); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
277 assert_text("whats going on", one); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
278 assert_text("well then", two); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
279 assert_text("", three); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
280 assert_text("bogus", four); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
281 } else { |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
282 panic!("wrong size!") |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
283 } |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
284 } |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
285 |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
286 #[test] |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
287 fn test_text_response() { |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
288 let mut responses = OwnedResponses::alloc(2); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
289 let text = RawTextResponse::fill(&mut responses[0], "hello").unwrap(); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
290 let data = text.contents().expect("valid"); |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
291 assert_eq!("hello", data); |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
292 text.free_contents(); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
293 text.free_contents(); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
294 RawTextResponse::fill(&mut responses[1], "hell\0").expect_err("should error; contains nul"); |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
295 } |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
296 |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
297 #[test] |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
298 fn test_binary_response() { |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
299 let mut responses = OwnedResponses::alloc(1); |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
300 let real_data = [1, 2, 3, 4, 5, 6, 7, 8]; |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
301 let resp = RawBinaryResponse::fill(&mut responses[0], &real_data, 7) |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
302 .expect("alloc should succeed"); |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
303 let data = resp.data(); |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
304 assert_eq!(&real_data, data); |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
305 assert_eq!(7, resp.data_type()); |
73
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
306 resp.free_contents(); |
ac6881304c78
Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
72
diff
changeset
|
307 resp.free_contents(); |
70
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
308 } |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
309 |
9f8381a1c09c
Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents:
69
diff
changeset
|
310 #[test] |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
311 #[ignore] |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
312 fn test_binary_response_too_big() { |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
313 let big_data: Vec<u8> = vec![0xFFu8; 10_000_000_000]; |
71
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
314 let mut responses = OwnedResponses::alloc(1); |
58f9d2a4df38
Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents:
70
diff
changeset
|
315 RawBinaryResponse::fill(&mut responses[0], &big_data, 0).expect_err("this is too big!"); |
69
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
316 } |
8f3ae0c7ab92
Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents:
66
diff
changeset
|
317 } |