Mercurial > crates > nonstick
changeset 79:2128123b9406
Format (oops!) and make some fun and/or stupid conversions available.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Sun, 08 Jun 2025 04:21:58 -0400 |
parents | 002adfb98c5c |
children | 5aa1a010f1e8 |
files | src/conv.rs src/libpam/answer.rs src/libpam/memory.rs src/libpam/question.rs |
diffstat | 4 files changed, 52 insertions(+), 55 deletions(-) [+] |
line wrap: on
line diff
--- a/src/conv.rs Sun Jun 08 03:48:40 2025 -0400 +++ b/src/conv.rs Sun Jun 08 04:21:58 2025 -0400 @@ -160,55 +160,47 @@ ); /// Owned binary data. -/// -/// You can take ownership of the stored data by destructuring it: -/// -/// ``` -/// # use nonstick::BinaryData; -/// # let binary_data = BinaryData::new(vec![99, 88, 77], 66); -/// let (data, data_type) = binary_data.into(); -/// ``` #[derive(Debug, Default, PartialEq)] pub struct BinaryData { - data: Vec<u8>, - data_type: u8, + /// The data. + pub data: Vec<u8>, + /// A tag describing the type of the data, to use how you please. + pub data_type: u8, } impl BinaryData { /// Creates a `BinaryData` with the given contents and type. pub fn new(data: impl Into<Vec<u8>>, data_type: u8) -> Self { - Self { data: data.into(), data_type } + Self { + data: data.into(), + data_type, + } + } +} + +impl<IV: Into<Vec<u8>>> From<(IV, u8)> for BinaryData { + /// Makes a new BinaryData from borrowed data. + fn from((data, data_type): (IV, u8)) -> Self { + Self { + data: data.into(), + data_type, + } } } impl From<BinaryData> for (Vec<u8>, u8) { + /// Easy destructuring. fn from(value: BinaryData) -> Self { (value.data, value.data_type) } } -impl From<(&'_[u8], u8)> for BinaryData { - fn from((data, data_type): (&'_[u8], u8)) -> Self { - Self { - data: data.to_vec(), - data_type, - } - } -} - -impl<'a> From<&'a BinaryData> for (&'a[u8], u8) { +impl<'a> From<&'a BinaryData> for (&'a [u8], u8) { fn from(value: &'a BinaryData) -> Self { (&value.data, value.data_type) } } -impl From<BinaryData> for Vec<u8> { - /// Takes ownership of the data stored herein. - fn from(value: BinaryData) -> Self { - value.data - } -} - q_and_a!( InfoMsg<'a, Q = &'a str, A = ()>, Message::Info, @@ -517,7 +509,7 @@ conv.communicate(&[radio.message(), bin.message()]); assert_eq!("zero", radio.answer().unwrap()); - assert_eq!(BinaryData::new(vec![5, 5, 5], 5), bin.answer().unwrap()); + assert_eq!(BinaryData::from(([5, 5, 5], 5)), bin.answer().unwrap()); } fn test_mux() { @@ -546,7 +538,7 @@ } Message::BinaryPrompt(prompt) => { assert_eq!((&[1, 2, 3][..], 69), prompt.question()); - prompt.set_answer(Ok(BinaryData::new(vec![3, 2, 1], 42))) + prompt.set_answer(Ok(BinaryData::from((&[3, 2, 1], 42)))) } Message::RadioPrompt(ask) => { assert_eq!("radio?", ask.question());
--- a/src/libpam/answer.rs Sun Jun 08 03:48:40 2025 -0400 +++ b/src/libpam/answer.rs Sun Jun 08 04:21:58 2025 -0400 @@ -232,8 +232,8 @@ use super::{Answer, Answers, BinaryAnswer, TextAnswer}; use crate::conv::{BinaryQAndA, ErrorMsg, InfoMsg, MaskedQAndA, QAndA, RadioQAndA}; use crate::libpam::conversation::OwnedMessage; + use crate::libpam::memory; use crate::BinaryData; - use crate::libpam::memory; #[test] fn test_round_trip() { @@ -295,7 +295,7 @@ #[test] fn test_text_answer() { let answer_ptr: *mut Answer = memory::calloc(1); - let answer = unsafe {&mut *answer_ptr}; + let answer = unsafe { &mut *answer_ptr }; TextAnswer::fill(answer, "hello").unwrap(); let zeroth_text = unsafe { TextAnswer::upcast(answer) }; let data = zeroth_text.contents().expect("valid"); @@ -310,7 +310,7 @@ fn test_binary_answer() { let answer_ptr: *mut Answer = memory::calloc(1); let answer = unsafe { &mut *answer_ptr }; - let real_data = BinaryData::new(vec![1, 2, 3, 4, 5, 6, 7, 8], 9); + let real_data = BinaryData::new([1, 2, 3, 4, 5, 6, 7, 8], 9); BinaryAnswer::fill(answer, (&real_data).into()).expect("alloc should succeed"); let bin_answer = unsafe { BinaryAnswer::upcast(answer) }; assert_eq!(real_data, bin_answer.data().into()); @@ -324,9 +324,8 @@ fn test_binary_answer_too_big() { let big_data: Vec<u8> = vec![0xFFu8; 10_000_000_000]; let answer_ptr: *mut Answer = memory::calloc(1); - let answer = unsafe {&mut*answer_ptr}; - BinaryAnswer::fill(answer, (&big_data, 100)) - .expect_err("this is too big!"); + let answer = unsafe { &mut *answer_ptr }; + BinaryAnswer::fill(answer, (&big_data, 100)).expect_err("this is too big!"); answer.free_contents(); unsafe { memory::free(answer) } }
--- a/src/libpam/memory.rs Sun Jun 08 03:48:40 2025 -0400 +++ b/src/libpam/memory.rs Sun Jun 08 04:21:58 2025 -0400 @@ -87,6 +87,7 @@ if data.contains(&0) { return Err(ErrorCode::ConversationError); } + // +1 for the null terminator let data_alloc: *mut c_char = calloc(data.len() + 1); // SAFETY: we just allocated this and we have enough room. unsafe { @@ -158,29 +159,37 @@ } } -impl<'a> From<&'a CBinaryData> for (&'a[u8], u8) { +impl<'a> From<&'a CBinaryData> for (&'a [u8], u8) { fn from(value: &'a CBinaryData) -> Self { - (unsafe { slice::from_raw_parts(value.data.as_ptr(), value.length()) }, - value.data_type ) + ( + unsafe { slice::from_raw_parts(value.data.as_ptr(), value.length()) }, + value.data_type, + ) + } +} + +impl From<&'_ CBinaryData> for BinaryData { + fn from(value: &'_ CBinaryData) -> Self { + // This is a dumb trick but I like it because it is simply the presence + // of `.map(|z: (_, _)| z)` in the middle of this that gives + // type inference the hint it needs to make this work. + let [ret] = [value].map(Into::into).map(|z: (_, _)| z).map(Into::into); + ret } } impl From<Option<&'_ CBinaryData>> for BinaryData { fn from(value: Option<&CBinaryData>) -> Self { - // This is a dumb trick but I like it because it is simply the presence - // of `.map(|(x, y)| (x, y))` in the middle of this that gives - // type inference the hint it needs to make this work. - value - .map(Into::into) - .map(|(data, data_type)| (data, data_type)) - .map(Into::into) - .unwrap_or_default() + value.map(Into::into).unwrap_or_default() } } #[cfg(test)] mod tests { - use super::{free, ErrorCode, CString, copy_pam_string, malloc_str, option_cstr, prompt_ptr, zero_c_string}; + use super::{ + copy_pam_string, free, malloc_str, option_cstr, prompt_ptr, zero_c_string, CString, + ErrorCode, + }; #[test] fn test_strings() { let str = malloc_str("hello there").unwrap();
--- a/src/libpam/question.rs Sun Jun 08 03:48:40 2025 -0400 +++ b/src/libpam/question.rs Sun Jun 08 04:21:58 2025 -0400 @@ -317,13 +317,10 @@ Message::RadioPrompt(p) => alloc(Style::RadioType, p.question()), Message::Error(p) => alloc(Style::ErrorMsg, p.question()), Message::Info(p) => alloc(Style::TextInfo, p.question()), - Message::BinaryPrompt(p) => { - let q = p.question(); - Ok(( - Style::BinaryPrompt, - CBinaryData::alloc(q)?.cast(), - )) - } + Message::BinaryPrompt(p) => Ok(( + Style::BinaryPrompt, + CBinaryData::alloc(p.question())?.cast(), + )), } }