annotate src/conv.rs @ 95:51c9d7e8261a

Return owned strings rather than borrowed strings. It's going to be irritating to have to work with strings borrowed from the PAM handle rather than just using your own. They're cheap enough to copy.
author Paul Fisher <paul@pfish.zone>
date Mon, 23 Jun 2025 14:03:44 -0400
parents db167f96ba46
children f3e260f9ddcb
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.
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
239 fn communicate(&mut 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 /// ```
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
265 pub fn conversation_func(func: impl FnMut(&[Message])) -> impl Conversation {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
266 Convo(func)
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
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
269 struct Convo<C: FnMut(&[Message])>(C);
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
270
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
271 impl<C: FnMut(&[Message])> Conversation for Convo<C> {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
272 fn communicate(&mut 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
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
277 /// 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
278 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
279 /// 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
280 /// 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
281 /// one at a time.
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
282 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
283 /// For example, to use a `Conversation` as a `SimpleConversation`:
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
284 ///
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
285 /// ```
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
286 /// # use nonstick::{Conversation, Result};
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
287 /// // Bring this trait into scope to get `masked_prompt`, among others.
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
288 /// use nonstick::SimpleConversation;
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
289 ///
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
290 /// fn ask_for_token(convo: &mut 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
291 /// 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
292 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
293 /// ```
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
294 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
295 /// or to use a `SimpleConversation` as a `Conversation`:
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
296 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
297 /// ```
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
298 /// use nonstick::{Conversation, SimpleConversation};
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
299 /// # use nonstick::{BinaryData, Result};
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
300 /// mod some_library {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
301 /// # use nonstick::Conversation;
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
302 /// 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
303 /// }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
304 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
305 ///
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
306 /// struct MySimpleConvo {/* ... */}
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
307 /// # 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
308 ///
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
309 /// impl SimpleConversation for MySimpleConvo {
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 /// # fn prompt(&mut self, request: &str) -> Result<String> {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
312 /// # unimplemented!()
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
313 /// # }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
314 /// #
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
315 /// # fn masked_prompt(&mut self, request: &str) -> Result<String> {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
316 /// # unimplemented!()
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
317 /// # }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
318 /// #
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
319 /// # fn error_msg(&mut self, message: &str) {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
320 /// # unimplemented!()
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
321 /// # }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
322 /// #
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
323 /// # fn info_msg(&mut self, message: &str) {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
324 /// # unimplemented!()
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
325 /// # }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
326 /// #
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
327 /// # fn radio_prompt(&mut self, request: &str) -> Result<String> {
94
db167f96ba46 Replace todo! with unimplemented! in documentation.
Paul Fisher <paul@pfish.zone>
parents: 93
diff changeset
328 /// # unimplemented!()
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
329 /// # }
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
330 /// #
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
331 /// # fn binary_prompt(&mut 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
332 /// # unimplemented!()
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
333 /// # }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
334 /// }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
335 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
336 /// fn main() {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
337 /// let mut simple = MySimpleConvo::new();
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
338 /// some_library::get_auth_data(&mut simple.as_conversation())
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 pub trait SimpleConversation {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
342 /// 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
343 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
344 /// 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
345 /// 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
346 /// then collects responses to return.
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
347 fn as_conversation(&mut self) -> Demux<'_, Self>
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
348 where
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
349 Self: Sized,
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
350 {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
351 Demux(self)
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
352 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
353 /// Prompts the user for something.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
354 fn prompt(&mut self, request: &str) -> Result<String>;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
355 /// Prompts the user for something, but hides what the user types.
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
356 fn masked_prompt(&mut self, request: &str) -> Result<String>;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
357 /// Alerts the user to an error.
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
358 fn error_msg(&mut self, message: &str);
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
359 /// Sends an informational message to the user.
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
360 fn info_msg(&mut self, message: &str);
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
361 /// \[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
362 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
363 /// 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
364 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
365 /// 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
366 /// this will return [`ErrorCode::ConversationError`].
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
367 /// 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
368 /// this will never be called.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
369 fn radio_prompt(&mut self, request: &str) -> Result<String> {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
370 let _ = request;
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
371 Err(ErrorCode::ConversationError)
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
372 }
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
373 /// \[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
374 ///
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
375 /// 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
376 /// this will return [`ErrorCode::ConversationError`].
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
377 /// 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
378 /// this will never be called.
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
379 fn binary_prompt(&mut self, data_and_type: (&[u8], u8)) -> Result<BinaryData> {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
380 let _ = data_and_type;
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
381 Err(ErrorCode::ConversationError)
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
382 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
383 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
384
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
385 macro_rules! conv_fn {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
386 ($(#[$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
387 $(#[$m])*
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
388 fn $fn_name(&mut 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
389 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
390 self.communicate(&[prompt.message()]);
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
391 prompt.answer()
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
392 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
393 };
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
394 ($(#[$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
395 $(#[$m])*
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
396 fn $fn_name(&mut self, $($param: $pt),*) {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
397 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
398 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
399 };
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
400 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
401
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
402 impl<C: Conversation> SimpleConversation for C {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
403 conv_fn!(prompt(message: &str) -> String { QAndA });
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
404 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
405 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
406 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
407 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
408 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
409 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
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 /// 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
412 ///
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
413 /// This is automatically created by [`SimpleConversation::as_conversation`].
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
414 pub struct Demux<'a, SC: SimpleConversation>(&'a mut SC);
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
415
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
416 impl<SC: SimpleConversation> Conversation for Demux<'_, SC> {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
417 fn communicate(&mut self, messages: &[Message]) {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
418 for msg in messages {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
419 match msg {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
420 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
421 Message::MaskedPrompt(prompt) => {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
422 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
423 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
424 Message::RadioPrompt(prompt) => {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
425 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
426 }
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
427 Message::Info(prompt) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
428 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
429 prompt.set_answer(Ok(()))
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
430 }
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
431 Message::Error(prompt) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
432 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
433 prompt.set_answer(Ok(()))
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
434 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
435 Message::BinaryPrompt(prompt) => {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
436 let q = prompt.question();
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
437 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
438 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
439 }
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
440 }
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
441 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
442 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
443
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
444 #[cfg(test)]
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
445 mod tests {
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
446 use super::*;
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
447 use crate::constants::ErrorCode;
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
448
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
449 #[test]
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
450 fn test_demux() {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
451 #[derive(Default)]
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
452 struct DemuxTester {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
453 error_ran: bool,
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
454 info_ran: bool,
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
455 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
456
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
457 impl SimpleConversation for DemuxTester {
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
458 fn prompt(&mut self, request: &str) -> Result<String> {
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
459 match request {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
460 "what" => Ok("whatwhat".to_owned()),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
461 "give_err" => Err(ErrorCode::PermissionDenied),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
462 _ => panic!("unexpected prompt!"),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
463 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
464 }
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
465 fn masked_prompt(&mut self, request: &str) -> Result<String> {
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
466 assert_eq!("reveal", request);
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
467 Ok("my secrets".to_owned())
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
468 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
469 fn error_msg(&mut self, message: &str) {
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
470 self.error_ran = true;
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
471 assert_eq!("whoopsie", message);
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
472 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
473 fn info_msg(&mut self, message: &str) {
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
474 self.info_ran = true;
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
475 assert_eq!("did you know", message);
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
476 }
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
477 fn radio_prompt(&mut self, request: &str) -> Result<String> {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
478 assert_eq!("channel?", request);
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
479 Ok("zero".to_owned())
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
480 }
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
481 fn binary_prompt(&mut self, data_and_type: (&[u8], u8)) -> Result<BinaryData> {
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
482 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
483 Ok(BinaryData::new(vec![5, 5, 5], 5))
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
484 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
485 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
486
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
487 let mut tester = DemuxTester::default();
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
488
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
489 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
490 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
491 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
492 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
493 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
494
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
495 let mut conv = tester.as_conversation();
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
496
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
497 // Basic tests.
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
498
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
499 conv.communicate(&[
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
500 what.message(),
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
501 pass.message(),
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
502 err.message(),
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
503 info.message(),
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
504 has_err.message(),
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
505 ]);
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
506
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
507 assert_eq!("whatwhat", what.answer().unwrap());
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
508 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
509 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
510 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
511 assert_eq!(ErrorCode::PermissionDenied, has_err.answer().unwrap_err());
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
512 assert!(tester.error_ran);
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
513 assert!(tester.info_ran);
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
514
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
515 // Test the Linux extensions separately.
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
516 {
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
517 let mut conv = tester.as_conversation();
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
518
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
519 let radio = RadioQAndA::new("channel?");
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
520 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
521 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
522
87
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
523 assert_eq!("zero", radio.answer().unwrap());
05291b601f0a Well and truly separate the Linux extensions.
Paul Fisher <paul@pfish.zone>
parents: 79
diff changeset
524 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
525 }
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
526 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
527
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
528 fn test_mux() {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
529 struct MuxTester;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
530
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
531 impl Conversation for MuxTester {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
532 fn communicate(&mut self, messages: &[Message]) {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
533 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
534 match *msg {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
535 Message::Info(info) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
536 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
537 info.set_answer(Ok(()))
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
538 }
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 76
diff changeset
539 Message::Error(error) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
540 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
541 error.set_answer(Ok(()))
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
542 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
543 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
544 "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
545 "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
546 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
547 }),
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
548 Message::MaskedPrompt(ask) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
549 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
550 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
551 }
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
552 Message::BinaryPrompt(prompt) => {
78
002adfb98c5c Rename files, reorder structs, remove annoying BorrowedBinaryData type.
Paul Fisher <paul@pfish.zone>
parents: 77
diff changeset
553 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
554 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
555 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
556 Message::RadioPrompt(ask) => {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
557 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
558 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
559 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
560 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
561 } else {
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
562 panic!(
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
563 "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
564 len = messages.len()
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
565 )
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
566 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
567 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
568 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
569
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
570 let mut tester = MuxTester;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
571
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
572 assert_eq!("answer", tester.prompt("question").unwrap());
93
efc2b56c8928 Remove undefined behavior per MIRI.
Paul Fisher <paul@pfish.zone>
parents: 87
diff changeset
573 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
574 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
575 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
576 // 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
577 {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
578 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
579 assert_eq!(
74
c7c596e6388f Make conversations type-safe (last big reorg) (REAL) (NOT CLICKBAIT)
Paul Fisher <paul@pfish.zone>
parents: 73
diff changeset
580 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
581 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
582 )
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
583 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
584 assert_eq!(
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
585 ErrorCode::BufferError,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
586 tester.prompt("should_error").unwrap_err(),
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 assert_eq!(
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
589 ErrorCode::ConversationError,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
590 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
591 )
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
592 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
593 }