annotate src/pam_ffi/conversation.rs @ 74:c7c596e6388f

Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT) In previous versions of Conversation, you could send messages and then return messages of the wrong type or in the wrong order or whatever. The receiver would then have to make sure that there were the right number of messages and that each message was the right type. That's annoying. This change makes the `Message` enum a two-way channel, where the asker puts their question into it, and then the answerer (the conversation) puts the answer in and returns control to the asker. The asker then only has to pull the Answer of the type they wanted out of the message.
author Paul Fisher <paul@pfish.zone>
date Fri, 06 Jun 2025 22:21:17 -0400
parents ac6881304c78
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
1 use crate::constants::Result;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
2 use crate::conv::{Conversation, Message, Response};
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
3 use crate::pam_ffi::memory::Immovable;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
4 use crate::pam_ffi::message::{MessageIndirector, OwnedMessages};
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
5 use crate::pam_ffi::response::{OwnedResponses, RawBinaryResponse, RawResponse, RawTextResponse};
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
6 use crate::ErrorCode;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
7 use crate::ErrorCode::ConversationError;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
8 use std::ffi::c_int;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
9 use std::iter;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
10 use std::marker::PhantomData;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
11 use std::result::Result as StdResult;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
12
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
13 /// An opaque structure that is passed through PAM in a conversation.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
14 #[repr(C)]
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
15 pub struct AppData {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
16 _data: (),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
17 _marker: Immovable,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
18 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
19
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
20 /// The callback that PAM uses to get information in a conversation.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
21 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
22 /// - `num_msg` is the number of messages in the `pam_message` array.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
23 /// - `messages` is a pointer to the messages being sent to the user.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
24 /// For details about its structure, see the documentation of
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
25 /// [`OwnedMessages`](super::OwnedMessages).
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
26 /// - `responses` is a pointer to an array of [`RawResponse`]s,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
27 /// which PAM sets in response to a module's request.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
28 /// This is an array of structs, not an array of pointers to a struct.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
29 /// There should always be exactly as many `responses` as `num_msg`.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
30 /// - `appdata` is the `appdata` field of the [`LibPamConversation`] we were passed.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
31 pub type ConversationCallback = unsafe extern "C" fn(
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
32 num_msg: c_int,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
33 messages: *const MessageIndirector,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
34 responses: *mut *mut RawResponse,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
35 appdata: *mut AppData,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
36 ) -> c_int;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
37
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
38 /// The type used by PAM to call back into a conversation.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
39 #[repr(C)]
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
40 pub struct LibPamConversation<'a> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
41 /// The function that is called to get information from the user.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
42 callback: ConversationCallback,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
43 /// The pointer that will be passed as the last parameter
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
44 /// to the conversation callback.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
45 appdata: *mut AppData,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
46 life: PhantomData<&'a mut ()>,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
47 _marker: Immovable,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
48 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
49
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
50 impl LibPamConversation<'_> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
51 fn wrap<C: Conversation>(conv: &mut C) -> Self {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
52 Self {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
53 callback: Self::wrapper_callback::<C>,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
54 appdata: (conv as *mut C).cast(),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
55 life: PhantomData,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
56 _marker: Immovable(PhantomData),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
57 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
58 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
59
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
60 unsafe extern "C" fn wrapper_callback<C: Conversation>(
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
61 count: c_int,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
62 messages: *const MessageIndirector,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
63 responses: *mut *mut RawResponse,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
64 me: *mut AppData,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
65 ) -> c_int {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
66 let call = || {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
67 let conv = me
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
68 .cast::<C>()
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
69 .as_mut()
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
70 .ok_or(ErrorCode::ConversationError)?;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
71 let indir = messages.as_ref().ok_or(ErrorCode::ConversationError)?;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
72 let response_ptr = responses.as_mut().ok_or(ErrorCode::ConversationError)?;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
73 let messages: Vec<Message> = indir
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
74 .iter(count as usize)
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
75 .map(Message::try_from)
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
76 .collect::<StdResult<_, _>>()
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
77 .map_err(|_| ErrorCode::ConversationError)?;
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
78 let responses = conv.communicate(&messages)?;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
79 let owned =
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
80 OwnedResponses::build(&responses).map_err(|_| ErrorCode::ConversationError)?;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
81 *response_ptr = owned.into_ptr();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
82 Ok(())
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
83 };
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
84 ErrorCode::result_to_c(call())
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
85 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
86 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
87
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
88 impl Conversation for LibPamConversation<'_> {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
89 fn communicate(&mut self, messages: &[Message]) -> Result<Vec<Response>> {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
90 let mut msgs_to_send = OwnedMessages::alloc(messages.len());
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
91 for (dst, src) in iter::zip(msgs_to_send.iter_mut(), messages.iter()) {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
92 dst.set(*src).map_err(|_| ErrorCode::ConversationError)?
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
93 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
94 let mut response_pointer = std::ptr::null_mut();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
95 // SAFETY: We're calling into PAM with valid everything.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
96 let result = unsafe {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
97 (self.callback)(
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
98 messages.len() as c_int,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
99 msgs_to_send.indirector(),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
100 &mut response_pointer,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
101 self.appdata,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
102 )
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
103 };
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
104 ErrorCode::result_from(result)?;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
105 // SAFETY: This is a pointer we just got back from PAM.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
106 let owned_responses =
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
107 unsafe { OwnedResponses::from_c_heap(response_pointer, messages.len()) };
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
108 convert_responses(messages, owned_responses)
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
109 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
110 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
111
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
112 fn convert_responses(
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
113 messages: &[Message],
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
114 mut raw_responses: OwnedResponses,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
115 ) -> Result<Vec<Response>> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
116 let pairs = iter::zip(messages.iter(), raw_responses.iter_mut());
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
117 // We first collect into a Vec of Results so that we always process
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
118 // every single entry, which may involve freeing it.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
119 let responses: Vec<_> = pairs.map(convert).collect();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
120 // Only then do we return the first error, if present.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
121 responses.into_iter().collect()
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
122 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
123
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
124 /// Converts one message-to-raw pair to a Response.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
125 fn convert((sent, received): (&Message, &mut RawResponse)) -> Result<Response> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
126 Ok(match sent {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
127 Message::MaskedPrompt(_) => {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
128 // SAFETY: Since this is a response to a text message,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
129 // we know it is text.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
130 let text_resp = unsafe { RawTextResponse::upcast(received) };
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
131 let ret = Response::MaskedText(
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
132 text_resp
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
133 .contents()
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
134 .map_err(|_| ErrorCode::ConversationError)?
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
135 .into(),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
136 );
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
137 // SAFETY: We're the only ones using this,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
138 // and we haven't freed it.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
139 text_resp.free_contents();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
140 ret
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
141 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
142 Message::Prompt(_) | Message::RadioPrompt(_) => {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
143 // SAFETY: Since this is a response to a text message,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
144 // we know it is text.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
145 let text_resp = unsafe { RawTextResponse::upcast(received) };
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
146 let ret = Response::Text(text_resp.contents().map_err(|_| ConversationError)?.into());
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
147 // SAFETY: We're the only ones using this,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
148 // and we haven't freed it.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
149 text_resp.free_contents();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
150 ret
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
151 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
152 Message::ErrorMsg(_) | Message::InfoMsg(_) => Response::NoResponse,
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
153 Message::BinaryPrompt { .. } => {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
154 let bin_resp = unsafe { RawBinaryResponse::upcast(received) };
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
155 let ret = Response::Binary(bin_resp.to_owned());
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
156 // SAFETY: We're the only ones using this,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
157 // and we haven't freed it.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
158 bin_resp.free_contents();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
159 ret
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
160 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
161 })
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
162 }