annotate src/conv.rs @ 98:b87100c5eed4

Start on environment variables, and make pointers nicer. This starts work on the PAM environment handling, and in so doing, introduces the CHeapBox and CHeapString structs. These are analogous to Box and CString, but they're located on the C heap rather than being Rust-managed memory. This is because environment variables deal with even more pointers and it turns out we can lose a lot of manual freeing using homemade smart pointers.
author Paul Fisher <paul@pfish.zone>
date Tue, 24 Jun 2025 04:25:25 -0400
parents f3e260f9ddcb
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
1 //! The PAM conversation and associated Stuff.
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents: 59
diff changeset
2
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
3 // Temporarily allowed until we get the actual conversation functions hooked up.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
4 #![allow(dead_code)]
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
5
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
6 use crate::constants::{ErrorCode, Result};
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
7 use std::cell::Cell;
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
8 use std::fmt;
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
9 use std::fmt::Debug;
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
10 use std::result::Result as StdResult;
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
11
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
12 /// The types of message and request that can be sent to a user.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
13 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
14 /// The data within each enum value is the prompt (or other information)
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
15 /// that will be presented to the user.
76
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
16 #[non_exhaustive]
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
17 pub enum Message<'a> {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
18 Prompt(&'a QAndA<'a>),
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
19 MaskedPrompt(&'a MaskedQAndA<'a>),
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
20 Error(&'a ErrorMsg<'a>),
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
21 Info(&'a InfoMsg<'a>),
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
22 RadioPrompt(&'a RadioQAndA<'a>),
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
23 BinaryPrompt(&'a BinaryQAndA<'a>),
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
24 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
25
76
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
26 impl Message<'_> {
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
27 /// Sets an error answer on this question, without having to inspect it.
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
28 ///
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
29 /// Use this as a default match case:
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
30 ///
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
31 /// ```
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
32 /// use nonstick::conv::{Message, QAndA};
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
33 /// use nonstick::ErrorCode;
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
34 ///
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
35 /// fn cant_respond(message: Message) {
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
36 /// match message {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
37 /// Message::Info(i) => {
76
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
38 /// eprintln!("fyi, {}", i.question());
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
39 /// i.set_answer(Ok(()))
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
40 /// }
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
41 /// Message::Error(e) => {
76
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
42 /// eprintln!("ERROR: {}", e.question());
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
43 /// e.set_answer(Ok(()))
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
44 /// }
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
45 /// // We can't answer any questions.
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
46 /// other => other.set_error(ErrorCode::ConversationError),
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
47 /// }
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
48 /// }
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
49 pub fn set_error(&self, err: ErrorCode) {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
50 match *self {
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
51 Message::Prompt(m) => m.set_answer(Err(err)),
76
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
52 Message::MaskedPrompt(m) => m.set_answer(Err(err)),
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
53 Message::Error(m) => m.set_answer(Err(err)),
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
54 Message::Info(m) => m.set_answer(Err(err)),
76
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
55 Message::RadioPrompt(m) => m.set_answer(Err(err)),
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
56 Message::BinaryPrompt(m) => m.set_answer(Err(err)),
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
57 }
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
58 }
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
59 }
e58d24849e82 Add Message::set_error to quickly answer a question with an error.
Paul Fisher <paul@pfish.zone>
parents: 74
diff changeset
60
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
61 macro_rules! q_and_a {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
62 ($(#[$m:meta])* $name:ident<'a, Q=$qt:ty, A=$at:ty>, $val:path) => {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
63 $(#[$m])*
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
64 pub struct $name<'a> {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
65 q: $qt,
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
66 a: Cell<Result<$at>>,
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
67 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
68
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
69 $(#[$m])*
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
70 impl<'a> $name<'a> {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
71 #[doc = concat!("Creates a `", stringify!($t), "` to be sent to the user.")]
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
72 pub fn new(question: $qt) -> Self {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
73 Self {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
74 q: question,
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
75 a: Cell::new(Err(ErrorCode::ConversationError)),
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
76 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
77 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
78
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
79 /// Converts this Q&A into a [`Message`] for the [`Conversation`].
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
80 pub fn message(&self) -> Message<'_> {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
81 $val(self)
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
82 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
83
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
84 /// The contents of the question being asked.
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
85 ///
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
86 /// For instance, this might say `"Username:"` to prompt the user
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
87 /// for their name, or the text of an error message.
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
88 pub fn question(&self) -> $qt {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
89 self.q
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
90 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
91
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
92 /// Sets the answer to the question.
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
93 ///
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
94 /// The [`Conversation`] implementation calls this to set the answer.
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
95 /// The conversation should *always call this function*,
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
96 /// even for Q&A messages that don't have "an answer"
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
97 /// (like error or info messages).
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
98 pub fn set_answer(&self, answer: Result<$at>) {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
99 self.a.set(answer)
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
100 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
101
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
102 /// Gets the answer to the question.
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
103 pub fn answer(self) -> Result<$at> {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
104 self.a.into_inner()
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
105 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
106 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
107
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
108 // shout out to stackoverflow user ballpointben for this lazy impl:
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
109 // https://stackoverflow.com/a/78871280/39808
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
110 $(#[$m])*
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
111 impl fmt::Debug for $name<'_> {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> StdResult<(), fmt::Error> {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
113 #[derive(Debug)]
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
114 struct $name<'a> { q: $qt }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
115 fmt::Debug::fmt(&$name { q: self.q }, f)
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
116 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
117 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
118 };
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
119 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
120
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
121 q_and_a!(
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
122 /// A Q&A that asks the user for text and does not show it while typing.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
123 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
124 /// In other words, a password entry prompt.
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
125 MaskedQAndA<'a, Q=&'a str, A=String>,
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
126 Message::MaskedPrompt
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
127 );
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
128
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
129 q_and_a!(
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
130 /// A standard Q&A prompt that asks the user for text.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
131 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
132 /// This is the normal "ask a person a question" prompt.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
133 /// When the user types, their input will be shown to them.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
134 /// It can be used for things like usernames.
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
135 QAndA<'a, Q=&'a str, A=String>,
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
136 Message::Prompt
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
137 );
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
138
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
139 q_and_a!(
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
140 /// A Q&A for "radio button"–style data. (Linux-PAM extension)
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
141 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
142 /// This message type is theoretically useful for "yes/no/maybe"
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
143 /// questions, but nowhere in the documentation is it specified
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
144 /// what the format of the answer will be, or how this should be shown.
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
145 RadioQAndA<'a, Q=&'a str, A=String>,
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
146 Message::RadioPrompt
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
147 );
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
148
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
149 q_and_a!(
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
150 /// Asks for binary data. (Linux-PAM extension)
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
151 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
152 /// This sends a binary message to the client application.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
153 /// It can be used to communicate with non-human logins,
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
154 /// or to enable things like security keys.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
155 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
156 /// The `data_type` tag is a value that is simply passed through
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
157 /// to the application. PAM does not define any meaning for it.
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
158 BinaryQAndA<'a, Q=(&'a [u8], u8), A=BinaryData>,
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
159 Message::BinaryPrompt
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
160 );
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
161
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
162 /// Owned binary data.
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
163 #[derive(Debug, Default, PartialEq)]
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
164 pub struct BinaryData {
79
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
165 /// The data.
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
166 pub data: Vec<u8>,
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
167 /// A tag describing the type of the data, to use how you please.
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
168 pub data_type: u8,
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
169 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
170
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
171 impl BinaryData {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
172 /// Creates a `BinaryData` with the given contents and type.
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
173 pub fn new(data: impl Into<Vec<u8>>, data_type: u8) -> Self {
79
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
174 Self {
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
175 data: data.into(),
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
176 data_type,
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
177 }
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
178 }
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
179 }
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
180
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
181 impl<IV: Into<Vec<u8>>> From<(IV, u8)> for BinaryData {
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
182 /// Makes a new BinaryData from borrowed data.
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
183 fn from((data, data_type): (IV, u8)) -> Self {
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
184 Self {
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
185 data: data.into(),
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
186 data_type,
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
187 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
188 }
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
189 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
190
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
191 impl From<BinaryData> for (Vec<u8>, u8) {
79
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
192 /// Easy destructuring.
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
193 fn from(value: BinaryData) -> Self {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
194 (value.data, value.data_type)
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
195 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
196 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
197
79
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
198 impl<'a> From<&'a BinaryData> for (&'a [u8], u8) {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
199 fn from(value: &'a BinaryData) -> Self {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
200 (&value.data, value.data_type)
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
201 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
202 }
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
203
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
204 q_and_a!(
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
205 /// A message containing information to be passed to the user.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
206 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
207 /// While this does not have an answer, [`Conversation`] implementations
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
208 /// should still call [`set_answer`][`QAndA::set_answer`] to verify that
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
209 /// the message has been displayed (or actively discarded).
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
210 InfoMsg<'a, Q = &'a str, A = ()>,
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
211 Message::Info
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
212 );
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
213
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
214 q_and_a!(
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
215 /// An error message to be passed to the user.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
216 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
217 /// While this does not have an answer, [`Conversation`] implementations
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
218 /// should still call [`set_answer`][`QAndA::set_answer`] to verify that
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
219 /// the message has been displayed (or actively discarded).
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
220 ErrorMsg<'a, Q = &'a str, A = ()>,
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
221 Message::Error
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
222 );
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
223
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
224 /// A channel for PAM modules to request information from the user.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
225 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
226 /// This trait is used by both applications and PAM modules:
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
227 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
228 /// - Applications implement Conversation and provide a user interface
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
229 /// to allow the user to respond to PAM questions.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
230 /// - Modules call a Conversation implementation to request information
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
231 /// or send information to the user.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
232 pub trait Conversation {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
233 /// Sends messages to the user.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
234 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
235 /// The returned Vec of messages always contains exactly as many entries
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
236 /// as there were messages in the request; one corresponding to each.
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
237 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
238 /// TODO: write detailed documentation about how to use this.
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
239 fn communicate(&self, messages: &[Message]);
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
240 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
241
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
242 /// Turns a simple function into a [`Conversation`].
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
243 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
244 /// This can be used to wrap a free-floating function for use as a
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
245 /// Conversation:
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
246 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
247 /// ```
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
248 /// use nonstick::conv::{conversation_func, Conversation, Message};
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
249 /// mod some_library {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
250 /// # use nonstick::Conversation;
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
251 /// pub fn get_auth_data(conv: &mut impl Conversation) {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
252 /// /* ... */
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
253 /// }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
254 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
255 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
256 /// fn my_terminal_prompt(messages: &[Message]) {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
257 /// // ...
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
258 /// # unimplemented!()
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
259 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
260 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
261 /// fn main() {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
262 /// some_library::get_auth_data(&mut conversation_func(my_terminal_prompt));
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
263 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
264 /// ```
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
265 pub fn conversation_func(func: impl Fn(&[Message])) -> impl Conversation {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
266 FunctionConvo(func)
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
267 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
268
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
269 struct FunctionConvo<C: Fn(&[Message])>(C);
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
270
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
271 impl<C: Fn(&[Message])> Conversation for FunctionConvo<C> {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
272 fn communicate(&self, messages: &[Message]) {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
273 self.0(messages)
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 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
276
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
277 /// A Conversation
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
278 struct UsernamePasswordConvo {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
279 username: String,
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
280 password: String,
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
281 }
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
282
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
283 /// A conversation trait for asking or answering one question at a time.
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
284 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
285 /// An implementation of this is provided for any [`Conversation`],
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
286 /// or a PAM application can implement this trait and handle messages
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
287 /// one at a time.
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
288 ///
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
289 /// For example, to use a `Conversation` as a `ConversationAdapter`:
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
290 ///
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
291 /// ```
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
292 /// # use nonstick::{Conversation, Result};
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
293 /// // Bring this trait into scope to get `masked_prompt`, among others.
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
294 /// use nonstick::ConversationAdapter;
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
295 ///
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
296 /// fn ask_for_token(convo: &impl Conversation) -> Result<String> {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
297 /// convo.masked_prompt("enter your one-time token")
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
298 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
299 /// ```
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
300 ///
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
301 /// or to use a `ConversationAdapter` as a `Conversation`:
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
302 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
303 /// ```
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
304 /// use nonstick::{Conversation, ConversationAdapter};
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
305 /// # use nonstick::{BinaryData, Result};
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
306 /// mod some_library {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
307 /// # use nonstick::Conversation;
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
308 /// pub fn get_auth_data(conv: &impl Conversation) { /* ... */
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
309 /// }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
310 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
311 ///
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
312 /// struct MySimpleConvo {/* ... */}
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
313 /// # impl MySimpleConvo { fn new() -> Self { Self{} } }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
314 ///
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
315 /// impl ConversationAdapter for MySimpleConvo {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
316 /// // ...
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
317 /// # fn prompt(&self, request: &str) -> Result<String> {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
318 /// # unimplemented!()
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
319 /// # }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
320 /// #
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
321 /// # fn masked_prompt(&self, request: &str) -> Result<String> {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
322 /// # unimplemented!()
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
323 /// # }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
324 /// #
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
325 /// # fn error_msg(&self, message: &str) {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
326 /// # unimplemented!()
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
327 /// # }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
328 /// #
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
329 /// # fn info_msg(&self, message: &str) {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
330 /// # unimplemented!()
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
331 /// # }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
332 /// #
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
333 /// # fn radio_prompt(&self, request: &str) -> Result<String> {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
334 /// # unimplemented!()
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
335 /// # }
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
336 /// #
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
337 /// # fn binary_prompt(&self, (data, data_type): (&[u8], u8)) -> Result<BinaryData> {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
338 /// # unimplemented!()
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
339 /// # }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
340 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
341 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
342 /// fn main() {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
343 /// let mut simple = MySimpleConvo::new();
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
344 /// some_library::get_auth_data(&mut simple.into_conversation())
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
345 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
346 /// ```
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
347 pub trait ConversationAdapter {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
348 /// Lets you use this simple conversation as a full [Conversation].
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
349 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
350 /// The wrapper takes each message received in [`Conversation::communicate`]
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
351 /// and passes them one-by-one to the appropriate method,
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
352 /// then collects responses to return.
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
353 fn into_conversation(self) -> Demux<Self>
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
354 where
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
355 Self: Sized,
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
356 {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
357 Demux(self)
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
358 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
359 /// Prompts the user for something.
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
360 fn prompt(&self, request: &str) -> Result<String>;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
361 /// Prompts the user for something, but hides what the user types.
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
362 fn masked_prompt(&self, request: &str) -> Result<String>;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
363 /// Alerts the user to an error.
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
364 fn error_msg(&self, message: &str);
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
365 /// Sends an informational message to the user.
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
366 fn info_msg(&self, message: &str);
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
367 /// \[Linux extension] Prompts the user for a yes/no/maybe conditional.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
368 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
369 /// PAM documentation doesn't define the format of the response.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
370 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
371 /// When called on an implementation that doesn't support radio prompts,
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
372 /// this will return [`ErrorCode::ConversationError`].
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
373 /// If implemented on an implementation that doesn't support radio prompts,
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
374 /// this will never be called.
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
375 fn radio_prompt(&self, request: &str) -> Result<String> {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
376 let _ = request;
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
377 Err(ErrorCode::ConversationError)
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
378 }
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
379 /// \[Linux extension] Requests binary data from the user.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
380 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
381 /// When called on an implementation that doesn't support radio prompts,
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
382 /// this will return [`ErrorCode::ConversationError`].
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
383 /// If implemented on an implementation that doesn't support radio prompts,
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
384 /// this will never be called.
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
385 fn binary_prompt(&self, data_and_type: (&[u8], u8)) -> Result<BinaryData> {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
386 let _ = data_and_type;
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
387 Err(ErrorCode::ConversationError)
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
388 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
389 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
390
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
391 impl<CA: ConversationAdapter> From<CA> for Demux<CA> {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
392 fn from(value: CA) -> Self {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
393 Demux(value)
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
394 }
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
395 }
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
396
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
397 macro_rules! conv_fn {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
398 ($(#[$m:meta])* $fn_name:ident($($param:tt: $pt:ty),+) -> $resp_type:ty { $msg:ty }) => {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
399 $(#[$m])*
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
400 fn $fn_name(&self, $($param: $pt),*) -> Result<$resp_type> {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
401 let prompt = <$msg>::new($($param),*);
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
402 self.communicate(&[prompt.message()]);
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
403 prompt.answer()
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
404 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
405 };
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
406 ($(#[$m:meta])*$fn_name:ident($($param:tt: $pt:ty),+) { $msg:ty }) => {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
407 $(#[$m])*
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
408 fn $fn_name(&self, $($param: $pt),*) {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
409 self.communicate(&[<$msg>::new($($param),*).message()]);
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
410 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
411 };
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
412 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
413
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
414 impl<C: Conversation> ConversationAdapter for C {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
415 conv_fn!(prompt(message: &str) -> String { QAndA });
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
416 conv_fn!(masked_prompt(message: &str) -> String { MaskedQAndA } );
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
417 conv_fn!(error_msg(message: &str) { ErrorMsg });
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
418 conv_fn!(info_msg(message: &str) { InfoMsg });
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
419 conv_fn!(radio_prompt(message: &str) -> String { RadioQAndA });
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
420 conv_fn!(binary_prompt((data, data_type): (&[u8], u8)) -> BinaryData { BinaryQAndA });
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
421 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
422
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
423 /// A [`Conversation`] which asks the questions one at a time.
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
424 ///
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
425 /// This is automatically created by [`ConversationAdapter::into_conversation`].
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
426 pub struct Demux<CA: ConversationAdapter>(CA);
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
427
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
428 impl<CA: ConversationAdapter> Demux<CA> {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
429 /// Gets the original Conversation out of this wrapper.
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
430 fn into_inner(self) -> CA {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
431 self.0
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
432 }
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
433 }
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
434
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
435 impl<CA: ConversationAdapter> Conversation for Demux<CA> {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
436 fn communicate(&self, messages: &[Message]) {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
437 for msg in messages {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
438 match msg {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
439 Message::Prompt(prompt) => prompt.set_answer(self.0.prompt(prompt.question())),
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
440 Message::MaskedPrompt(prompt) => {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
441 prompt.set_answer(self.0.masked_prompt(prompt.question()))
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
442 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
443 Message::RadioPrompt(prompt) => {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
444 prompt.set_answer(self.0.radio_prompt(prompt.question()))
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
445 }
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
446 Message::Info(prompt) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
447 self.0.info_msg(prompt.question());
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
448 prompt.set_answer(Ok(()))
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
449 }
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
450 Message::Error(prompt) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
451 self.0.error_msg(prompt.question());
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
452 prompt.set_answer(Ok(()))
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
453 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
454 Message::BinaryPrompt(prompt) => {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
455 let q = prompt.question();
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
456 prompt.set_answer(self.0.binary_prompt(q))
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
457 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
458 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
459 }
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
460 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
461 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
462
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
463 #[cfg(test)]
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
464 mod tests {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
465 use super::*;
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
466 use crate::constants::ErrorCode;
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
467
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
468 #[test]
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
469 fn test_demux() {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
470 #[derive(Default)]
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
471 struct DemuxTester {
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
472 error_ran: Cell<bool>,
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
473 info_ran: Cell<bool>,
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
474 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
475
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
476 impl ConversationAdapter for DemuxTester {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
477 fn prompt(&self, request: &str) -> Result<String> {
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
478 match request {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
479 "what" => Ok("whatwhat".to_owned()),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
480 "give_err" => Err(ErrorCode::PermissionDenied),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
481 _ => panic!("unexpected prompt!"),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
482 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
483 }
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
484 fn masked_prompt(&self, request: &str) -> Result<String> {
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
485 assert_eq!("reveal", request);
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
486 Ok("my secrets".to_owned())
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
487 }
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
488 fn error_msg(&self, message: &str) {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
489 self.error_ran.set(true);
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
490 assert_eq!("whoopsie", message);
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
491 }
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
492 fn info_msg(&self, message: &str) {
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
493 self.info_ran.set(true);
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
494 assert_eq!("did you know", message);
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
495 }
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
496 fn radio_prompt(&self, request: &str) -> Result<String> {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
497 assert_eq!("channel?", request);
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
498 Ok("zero".to_owned())
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
499 }
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
500 fn binary_prompt(&self, data_and_type: (&[u8], u8)) -> Result<BinaryData> {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
501 assert_eq!((&[10, 9, 8][..], 66), data_and_type);
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
502 Ok(BinaryData::new(vec![5, 5, 5], 5))
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
503 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
504 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
505
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
506 let tester = DemuxTester::default();
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
507
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
508 let what = QAndA::new("what");
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
509 let pass = MaskedQAndA::new("reveal");
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
510 let err = ErrorMsg::new("whoopsie");
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
511 let info = InfoMsg::new("did you know");
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
512 let has_err = QAndA::new("give_err");
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
513
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
514 let conv = tester.into_conversation();
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
515
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
516 // Basic tests.
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
517
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
518 conv.communicate(&[
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
519 what.message(),
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
520 pass.message(),
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
521 err.message(),
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
522 info.message(),
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
523 has_err.message(),
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
524 ]);
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
525
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
526 assert_eq!("whatwhat", what.answer().unwrap());
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
527 assert_eq!("my secrets", pass.answer().unwrap());
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
528 assert_eq!(Ok(()), err.answer());
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
529 assert_eq!(Ok(()), info.answer());
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
530 assert_eq!(ErrorCode::PermissionDenied, has_err.answer().unwrap_err());
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
531 let tester = conv.into_inner();
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
532 assert!(tester.error_ran.get());
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
533 assert!(tester.info_ran.get());
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
534
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
535 // Test the Linux extensions separately.
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
536 {
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
537 let conv = tester.into_conversation();
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
538
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
539 let radio = RadioQAndA::new("channel?");
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
540 let bin = BinaryQAndA::new((&[10, 9, 8], 66));
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
541 conv.communicate(&[radio.message(), bin.message()]);
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
542
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
543 assert_eq!("zero", radio.answer().unwrap());
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
544 assert_eq!(BinaryData::from(([5, 5, 5], 5)), bin.answer().unwrap());
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
545 }
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
546 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
547
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
548 fn test_mux() {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
549 struct MuxTester;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
550
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
551 impl Conversation for MuxTester {
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
552 fn communicate(&self, messages: &[Message]) {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
553 if let [msg] = messages {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
554 match *msg {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
555 Message::Info(info) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
556 assert_eq!("let me tell you", info.question());
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
557 info.set_answer(Ok(()))
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
558 }
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
559 Message::Error(error) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
560 assert_eq!("oh no", error.question());
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
561 error.set_answer(Ok(()))
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
562 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
563 Message::Prompt(prompt) => prompt.set_answer(match prompt.question() {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
564 "should_err" => Err(ErrorCode::PermissionDenied),
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
565 "question" => Ok("answer".to_owned()),
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
566 other => panic!("unexpected question {other:?}"),
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
567 }),
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
568 Message::MaskedPrompt(ask) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
569 assert_eq!("password!", ask.question());
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
570 ask.set_answer(Ok("open sesame".into()))
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
571 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
572 Message::BinaryPrompt(prompt) => {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
573 assert_eq!((&[1, 2, 3][..], 69), prompt.question());
79
2128123b9406 Format (oops!) and make some fun and/or stupid conversions available.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
574 prompt.set_answer(Ok(BinaryData::from((&[3, 2, 1], 42))))
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
575 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
576 Message::RadioPrompt(ask) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
577 assert_eq!("radio?", ask.question());
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
578 ask.set_answer(Ok("yes".to_owned()))
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
579 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
580 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
581 } else {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
582 panic!(
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
583 "there should only be one message, not {len}",
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
584 len = messages.len()
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
585 )
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
586 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
587 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
588 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
589
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 94
diff changeset
590 let tester = MuxTester;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
591
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
592 assert_eq!("answer", tester.prompt("question").unwrap());
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
593 assert_eq!("open sesame", tester.masked_prompt("password!").unwrap());
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
594 tester.error_msg("oh no");
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
595 tester.info_msg("let me tell you");
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
596 // Linux-PAM extensions. Always implemented, but separate for clarity.
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
597 {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
598 assert_eq!("yes", tester.radio_prompt("radio?").unwrap());
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
599 assert_eq!(
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
600 BinaryData::new(vec![3, 2, 1], 42),
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
601 tester.binary_prompt((&[1, 2, 3], 69)).unwrap(),
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
602 )
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
603 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
604 assert_eq!(
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
605 ErrorCode::BufferError,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
606 tester.prompt("should_error").unwrap_err(),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
607 );
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
608 assert_eq!(
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
609 ErrorCode::ConversationError,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
610 tester.masked_prompt("return_wrong_type").unwrap_err()
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
611 )
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
612 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
613 }