Browse Source

Apply some suggestions

pull/78/head
TechiePi 2 years ago
parent
commit
7ca152a02a
  1. 114
      ctru-rs/src/applets/mii_selector.rs
  2. 174
      ctru-rs/src/mii.rs

114
ctru-rs/src/applets/mii_selector.rs

@ -28,13 +28,16 @@ pub struct MiiSelector {
} }
pub struct MiiSelectorReturn { pub struct MiiSelectorReturn {
raw_return: Box<ctru_sys::MiiSelectorReturn>,
pub mii_data: MiiData, pub mii_data: MiiData,
pub is_mii_selected: bool, pub is_mii_selected: bool,
pub mii_type: MiiType, pub mii_type: MiiType,
pub checksum: u16, pub checksum: u16,
} }
pub enum MiiLaunchError {
InvalidChecksum,
}
impl MiiSelector { impl MiiSelector {
pub fn init() -> Self { pub fn init() -> Self {
let mut config = Box::<ctru_sys::MiiSelectorConf>::default(); let mut config = Box::<ctru_sys::MiiSelectorConf>::default();
@ -47,7 +50,7 @@ impl MiiSelector {
pub fn set_title(&mut self, text: &str) { pub fn set_title(&mut self, text: &str) {
// This can only fail if the text contains NUL bytes in the string... which seems // This can only fail if the text contains NUL bytes in the string... which seems
// unlikely and is documented // unlikely and is documented
let c_text = CString::new(text).expect("Cstring::new failed"); let c_text = CString::new(text).expect("Failed to convert the title text into a CString");
unsafe { unsafe {
ctru_sys::miiSelectorSetTitle(self.config.as_mut(), c_text.as_ptr()); ctru_sys::miiSelectorSetTitle(self.config.as_mut(), c_text.as_ptr());
} }
@ -58,59 +61,39 @@ impl MiiSelector {
} }
pub fn whitelist_guest_mii(&mut self, mii_index: MiiConfigIndex) { pub fn whitelist_guest_mii(&mut self, mii_index: MiiConfigIndex) {
match mii_index { let index = match mii_index {
MiiConfigIndex::Index(i) => unsafe { MiiConfigIndex::Index(i) => i,
ctru_sys::miiSelectorWhitelistGuestMii(self.config.as_mut(), i) MiiConfigIndex::All => ctru_sys::MIISELECTOR_GUESTMII_SLOTS,
}, };
MiiConfigIndex::All => unsafe {
ctru_sys::miiSelectorWhitelistGuestMii( unsafe { ctru_sys::miiSelectorWhitelistGuestMii(self.config.as_mut(), index) }
self.config.as_mut(),
ctru_sys::MIISELECTOR_GUESTMII_SLOTS,
)
},
}
} }
pub fn blacklist_guest_mii(&mut self, mii_index: MiiConfigIndex) { pub fn blacklist_guest_mii(&mut self, mii_index: MiiConfigIndex) {
match mii_index { let index = match mii_index {
MiiConfigIndex::Index(i) => unsafe { MiiConfigIndex::Index(i) => i,
ctru_sys::miiSelectorBlacklistGuestMii(self.config.as_mut(), i) MiiConfigIndex::All => ctru_sys::MIISELECTOR_GUESTMII_SLOTS,
}, };
MiiConfigIndex::All => unsafe {
ctru_sys::miiSelectorBlacklistGuestMii( unsafe { ctru_sys::miiSelectorBlacklistGuestMii(self.config.as_mut(), index) }
self.config.as_mut(),
ctru_sys::MIISELECTOR_GUESTMII_SLOTS,
)
},
}
} }
pub fn whitelist_user_mii(&mut self, mii_index: MiiConfigIndex) { pub fn whitelist_user_mii(&mut self, mii_index: MiiConfigIndex) {
match mii_index { let index = match mii_index {
MiiConfigIndex::Index(i) => unsafe { MiiConfigIndex::Index(i) => i,
ctru_sys::miiSelectorWhitelistUserMii(self.config.as_mut(), i) MiiConfigIndex::All => ctru_sys::MIISELECTOR_USERMII_SLOTS,
}, };
MiiConfigIndex::All => unsafe {
ctru_sys::miiSelectorWhitelistUserMii( unsafe { ctru_sys::miiSelectorWhitelistUserMii(self.config.as_mut(), index) }
self.config.as_mut(),
ctru_sys::MIISELECTOR_USERMII_SLOTS,
)
},
}
} }
pub fn blacklist_user_mii(&mut self, mii_index: MiiConfigIndex) { pub fn blacklist_user_mii(&mut self, mii_index: MiiConfigIndex) {
match mii_index { let index = match mii_index {
MiiConfigIndex::Index(i) => unsafe { MiiConfigIndex::Index(i) => i,
ctru_sys::miiSelectorBlacklistUserMii(self.config.as_mut(), i) MiiConfigIndex::All => ctru_sys::MIISELECTOR_USERMII_SLOTS,
}, };
MiiConfigIndex::All => unsafe {
ctru_sys::miiSelectorBlacklistUserMii( unsafe { ctru_sys::miiSelectorBlacklistUserMii(self.config.as_mut(), index) }
self.config.as_mut(),
ctru_sys::MIISELECTOR_USERMII_SLOTS,
)
},
}
} }
// This function is static inline in libctru // This function is static inline in libctru
@ -119,54 +102,27 @@ impl MiiSelector {
self.config.initial_index = index self.config.initial_index = index
} }
pub fn launch(&mut self) -> MiiSelectorReturn { pub fn launch(&mut self) -> Result<MiiSelectorReturn, MiiLaunchError> {
let mut return_val = Box::<ctru_sys::MiiSelectorReturn>::default(); let mut return_val = Box::<ctru_sys::MiiSelectorReturn>::default();
unsafe { ctru_sys::miiSelectorLaunch(self.config.as_mut(), return_val.as_mut()) } unsafe { ctru_sys::miiSelectorLaunch(self.config.as_mut(), return_val.as_mut()) }
return_val.into() if unsafe { ctru_sys::miiSelectorChecksumIsValid(return_val.as_mut()) } {
} Ok(return_val.into())
} } else {
Err(MiiLaunchError::InvalidChecksum)
impl MiiSelectorReturn {
pub fn name(&self) -> String {
let mut tmp = [0u8; 36];
unsafe {
ctru_sys::miiSelectorReturnGetName(self.raw_return.as_ref(), tmp.as_mut_ptr(), 36)
}
let len = unsafe { libc::strlen(tmp.as_ptr()) };
let utf8 = unsafe { std::str::from_utf8_unchecked(&tmp[..len]) };
utf8.to_owned()
}
pub fn author(&self) -> String {
let mut tmp = [0u8; 30];
unsafe {
ctru_sys::miiSelectorReturnGetAuthor(self.raw_return.as_ref(), tmp.as_mut_ptr(), 30)
} }
let len = unsafe { libc::strlen(tmp.as_ptr()) };
let utf8 = unsafe { std::str::from_utf8_unchecked(&tmp[..len]) };
utf8.to_owned()
}
pub fn valid_checksum(&self) -> bool {
unsafe { ctru_sys::miiSelectorChecksumIsValid(self.raw_return.as_ref()) }
} }
} }
impl From<Box<ctru_sys::MiiSelectorReturn>> for MiiSelectorReturn { impl From<Box<ctru_sys::MiiSelectorReturn>> for MiiSelectorReturn {
fn from(ret: Box<ctru_sys::MiiSelectorReturn>) -> Self { fn from(ret: Box<ctru_sys::MiiSelectorReturn>) -> Self {
let checksum = ret.checksum; let checksum = ret.checksum;
let raw_mii_data = ret.mii._bindgen_opaque_blob; let raw_mii_data = ret.mii;
let no_mii_selected = ret.no_mii_selected; let no_mii_selected = ret.no_mii_selected;
let guest_mii_index_clone = ret.guest_mii_index; let guest_mii_index_clone = ret.guest_mii_index;
let mut guest_mii_name = ret.guest_mii_name; let mut guest_mii_name = ret.guest_mii_name;
MiiSelectorReturn { MiiSelectorReturn {
raw_return: ret,
mii_data: raw_mii_data.into(), mii_data: raw_mii_data.into(),
is_mii_selected: no_mii_selected == 0, is_mii_selected: no_mii_selected == 0,
mii_type: if guest_mii_index_clone != 0xFFFFFFFF { mii_type: if guest_mii_index_clone != 0xFFFFFFFF {

174
ctru-rs/src/mii.rs

@ -1,4 +1,4 @@
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum RegionLock { pub enum RegionLock {
None, None,
Japan, Japan,
@ -6,7 +6,7 @@ pub enum RegionLock {
Europe, Europe,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Charset { pub enum Charset {
JapanUSAEurope, JapanUSAEurope,
China, China,
@ -14,7 +14,7 @@ pub enum Charset {
Taiwan, Taiwan,
} }
#[derive(Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct MiiDataOptions { pub struct MiiDataOptions {
pub is_copying_allowed: bool, pub is_copying_allowed: bool,
pub is_profanity_flag_enabled: bool, pub is_profanity_flag_enabled: bool,
@ -22,13 +22,13 @@ pub struct MiiDataOptions {
pub charset: Charset, pub charset: Charset,
} }
#[derive(Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct SelectorPosition { pub struct SelectorPosition {
pub page_index: u8, pub page_index: u8,
pub slot_index: u8, pub slot_index: u8,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum OriginConsole { pub enum OriginConsole {
ConsoleWii, ConsoleWii,
ConsoleDSi, ConsoleDSi,
@ -36,18 +36,18 @@ pub enum OriginConsole {
ConsoleWiiUSwitch, ConsoleWiiUSwitch,
} }
#[derive(Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct ConsoleIdentity { pub struct ConsoleIdentity {
pub origin_console: OriginConsole, pub origin_console: OriginConsole,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum MiiSex { pub enum MiiSex {
Male, Male,
Female, Female,
} }
#[derive(Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct Details { pub struct Details {
pub sex: MiiSex, pub sex: MiiSex,
pub birthday_month: u8, pub birthday_month: u8,
@ -56,26 +56,26 @@ pub struct Details {
pub is_favorite: bool, pub is_favorite: bool,
} }
#[derive(Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct FaceStyle { pub struct FaceStyle {
pub is_sharing_enabled: bool, pub is_sharing_enabled: bool,
pub shape: u8, pub shape: u8,
pub skin_color: u8, pub skin_color: u8,
} }
#[derive(Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct FaceDetails { pub struct FaceDetails {
pub wrinkles: u8, pub wrinkles: u8,
pub makeup: u8, pub makeup: u8,
} }
#[derive(Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct HairDetails { pub struct HairDetails {
pub color: u8, pub color: u8,
pub is_flipped: bool, pub is_flipped: bool,
} }
#[derive(Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct EyeDetails { pub struct EyeDetails {
pub style: u8, pub style: u8,
pub color: u8, pub color: u8,
@ -86,7 +86,7 @@ pub struct EyeDetails {
pub y_position: u8, pub y_position: u8,
} }
#[derive(Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct EyebrowDetails { pub struct EyebrowDetails {
pub style: u8, pub style: u8,
pub color: u8, pub color: u8,
@ -97,14 +97,14 @@ pub struct EyebrowDetails {
pub y_position: u8, pub y_position: u8,
} }
#[derive(Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct NoseDetails { pub struct NoseDetails {
pub style: u8, pub style: u8,
pub scale: u8, pub scale: u8,
pub y_position: u8, pub y_position: u8,
} }
#[derive(Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct MouthDetails { pub struct MouthDetails {
pub style: u8, pub style: u8,
pub color: u8, pub color: u8,
@ -112,13 +112,13 @@ pub struct MouthDetails {
pub y_scale: u8, pub y_scale: u8,
} }
#[derive(Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct MustacheDetails { pub struct MustacheDetails {
pub mouth_y_position: u8, pub mouth_y_position: u8,
pub mustache_style: u8, pub mustache_style: u8,
} }
#[derive(Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct BeardDetails { pub struct BeardDetails {
pub style: u8, pub style: u8,
pub color: u8, pub color: u8,
@ -126,7 +126,7 @@ pub struct BeardDetails {
pub y_position: u8, pub y_position: u8,
} }
#[derive(Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct GlassDetails { pub struct GlassDetails {
pub style: u8, pub style: u8,
pub color: u8, pub color: u8,
@ -134,7 +134,7 @@ pub struct GlassDetails {
pub y_position: u8, pub y_position: u8,
} }
#[derive(Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct MoleDetails { pub struct MoleDetails {
pub is_enabled: bool, pub is_enabled: bool,
pub scale: u8, pub scale: u8,
@ -144,15 +144,15 @@ pub struct MoleDetails {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct MiiData { pub struct MiiData {
pub mii_options: MiiDataOptions, pub options: MiiDataOptions,
pub mii_selector_position: SelectorPosition, pub selector_position: SelectorPosition,
pub mii_console_identity: ConsoleIdentity, pub console_identity: ConsoleIdentity,
pub system_id: [u8; 8], pub system_id: [u8; 8],
pub mac_address: [u8; 6], pub mac_address: [u8; 6],
pub mii_details: Details, pub details: Details,
pub mii_name: String, pub name: String,
pub height: u8, pub height: u8,
pub width: u8, pub width: u8,
@ -175,8 +175,9 @@ pub struct MiiData {
pub author_name: String, pub author_name: String,
} }
impl From<[u8; 92]> for MiiData { impl From<ctru_sys::MiiData> for MiiData {
fn from(raw_mii_data: [u8; 92]) -> Self { fn from(mii_data: ctru_sys::MiiData) -> Self {
let raw_mii_data = mii_data._bindgen_opaque_blob;
// Source for the representation and what each thing means: https://www.3dbrew.org/wiki/Mii // Source for the representation and what each thing means: https://www.3dbrew.org/wiki/Mii
let raw_options = vec_bit(raw_mii_data[0x1]); let raw_options = vec_bit(raw_mii_data[0x1]);
let raw_position = vec_bit(raw_mii_data[0x2]); let raw_position = vec_bit(raw_mii_data[0x2]);
@ -200,10 +201,10 @@ impl From<[u8; 92]> for MiiData {
raw_mii_data[0x15], raw_mii_data[0x15],
]; ];
let raw_details: [bool; 16] = let raw_details: [bool; 16] =
get_and_concat_vec_bit(raw_mii_data.as_slice(), &[0x18, 0x19]) get_and_concat_vec_bit(&raw_mii_data, &[0x18, 0x19])
.try_into() .try_into()
.unwrap(); .unwrap();
let raw_utf16_name = &raw_mii_data.as_slice()[0x1A..0x2D]; let raw_utf16_name = &raw_mii_data[0x1A..0x2D];
let height = raw_mii_data[0x2E]; let height = raw_mii_data[0x2E];
let width = raw_mii_data[0x2F]; let width = raw_mii_data[0x2F];
let raw_face_style = vec_bit(raw_mii_data[0x30]); let raw_face_style = vec_bit(raw_mii_data[0x30]);
@ -211,75 +212,59 @@ impl From<[u8; 92]> for MiiData {
let hair_style = raw_mii_data[0x32]; let hair_style = raw_mii_data[0x32];
let raw_hair_details = vec_bit(raw_mii_data[0x33]); let raw_hair_details = vec_bit(raw_mii_data[0x33]);
let raw_eye_details: [bool; 32] = let raw_eye_details: [bool; 32] =
get_and_concat_vec_bit(raw_mii_data.as_slice(), &[0x34, 0x35, 0x36, 0x37]) get_and_concat_vec_bit(&raw_mii_data, &[0x34, 0x35, 0x36, 0x37])
.try_into() .try_into()
.unwrap(); .unwrap();
let raw_eyebrow_details: [bool; 32] = let raw_eyebrow_details: [bool; 32] =
get_and_concat_vec_bit(raw_mii_data.as_slice(), &[0x38, 0x39, 0x3A, 0x3B]) get_and_concat_vec_bit(&raw_mii_data, &[0x38, 0x39, 0x3A, 0x3B])
.try_into() .try_into()
.unwrap(); .unwrap();
let raw_nose_details: [bool; 16] = let raw_nose_details: [bool; 16] =
get_and_concat_vec_bit(raw_mii_data.as_slice(), &[0x3C, 0x3D]) get_and_concat_vec_bit(&raw_mii_data, &[0x3C, 0x3D])
.try_into() .try_into()
.unwrap(); .unwrap();
let raw_mouth_details: [bool; 16] = let raw_mouth_details: [bool; 16] =
get_and_concat_vec_bit(raw_mii_data.as_slice(), &[0x3E, 0x3F]) get_and_concat_vec_bit(&raw_mii_data, &[0x3E, 0x3F])
.try_into() .try_into()
.unwrap(); .unwrap();
let raw_mustache_details: [bool; 16] = let raw_mustache_details: [bool; 16] =
get_and_concat_vec_bit(raw_mii_data.as_slice(), &[0x40, 0x41]) get_and_concat_vec_bit(&raw_mii_data, &[0x40, 0x41])
.try_into() .try_into()
.unwrap(); .unwrap();
let raw_beard_details: [bool; 16] = let raw_beard_details: [bool; 16] =
get_and_concat_vec_bit(raw_mii_data.as_slice(), &[0x42, 0x42]) get_and_concat_vec_bit(&raw_mii_data, &[0x42, 0x42])
.try_into() .try_into()
.unwrap(); .unwrap();
let raw_glass_details: [bool; 16] = let raw_glass_details: [bool; 16] =
get_and_concat_vec_bit(raw_mii_data.as_slice(), &[0x44, 0x45]) get_and_concat_vec_bit(&raw_mii_data, &[0x44, 0x45])
.try_into() .try_into()
.unwrap(); .unwrap();
let raw_mole_details: [bool; 16] = let raw_mole_details: [bool; 16] =
get_and_concat_vec_bit(raw_mii_data.as_slice(), &[0x46, 0x47]) get_and_concat_vec_bit(&raw_mii_data, &[0x46, 0x47])
.try_into() .try_into()
.unwrap(); .unwrap();
let raw_utf16_author = &raw_mii_data.as_slice()[0x48..0x5C]; let raw_utf16_author = &raw_mii_data[0x48..0x5C];
let mii_name = utf16_byte_pairs_to_string(raw_utf16_name); let mii_name = utf16_byte_pairs_to_string(raw_utf16_name);
let author_name = utf16_byte_pairs_to_string(raw_utf16_author); let author_name = utf16_byte_pairs_to_string(raw_utf16_author);
let options = MiiDataOptions { let options = MiiDataOptions {
is_copying_allowed: *raw_options.first().unwrap(), is_copying_allowed: raw_options[0],
is_profanity_flag_enabled: *raw_options.get(1).unwrap(), is_profanity_flag_enabled: raw_options[1],
region_lock: { region_lock: {
let first_bit = raw_options[3]; match (raw_options[3], raw_options[2]) {
let second_bit = raw_options[2]; (false, false) => RegionLock::None,
if !first_bit && !second_bit { (false, true) => RegionLock::Japan,
// 0b00 (true, false) => RegionLock::USA,
RegionLock::None (true, true) => RegionLock::Europe,
} else if !first_bit && second_bit {
// 0b01
RegionLock::Japan
} else if first_bit && !second_bit {
// 0b10
RegionLock::USA
} else {
RegionLock::Europe
} }
}, },
charset: { charset: {
let first_bit = raw_options[5]; match (raw_options[5], raw_options[4]) {
let second_bit = raw_options[4]; (false, false) => Charset::JapanUSAEurope,
if !first_bit && !second_bit { (false, true) => Charset::China,
// 0b00 (true, false) => Charset::Korea,
Charset::JapanUSAEurope (true, true) => Charset::Taiwan,
} else if !first_bit && second_bit {
// 0b01
Charset::China
} else if first_bit && !second_bit {
// 0b10
Charset::Korea
} else {
Charset::Taiwan
} }
}, },
}; };
@ -291,29 +276,20 @@ impl From<[u8; 92]> for MiiData {
let device = ConsoleIdentity { let device = ConsoleIdentity {
origin_console: { origin_console: {
let first_bit = raw_device[6]; match (raw_device[6], raw_device[5], raw_device[4]) {
let second_bit = raw_device[5]; (false, false, true) => OriginConsole::ConsoleWii,
let third_bit = raw_device[4]; (false, true, false) => OriginConsole::ConsoleDSi,
(false, true, true) => OriginConsole::Console3DS,
if !first_bit && !second_bit && third_bit { _ => OriginConsole::ConsoleWiiUSwitch,
OriginConsole::ConsoleWii
} else if !first_bit && second_bit && !third_bit {
OriginConsole::ConsoleDSi
} else if !first_bit && second_bit && third_bit {
OriginConsole::Console3DS
} else {
OriginConsole::ConsoleWiiUSwitch
} }
}, },
}; };
let details = Details { let details = Details {
sex: { sex: {
let first_bit = raw_details[0]; match raw_details[0] {
if first_bit { true => MiiSex::Female,
MiiSex::Female false => MiiSex::Male,
} else {
MiiSex::Male
} }
}, },
birthday_month: partial_vec_to_u8_with_reverse(&raw_details[1..4]), birthday_month: partial_vec_to_u8_with_reverse(&raw_details[1..4]),
@ -398,13 +374,13 @@ impl From<[u8; 92]> for MiiData {
}; };
MiiData { MiiData {
mii_options: options, options: options,
mii_selector_position: position, selector_position: position,
mii_console_identity: device, console_identity: device,
system_id, system_id,
mac_address: creator_mac, mac_address: creator_mac,
mii_details: details, details: details,
mii_name, name: mii_name,
height, height,
width, width,
face_style, face_style,
@ -438,12 +414,9 @@ fn vec_bit(data: u8) -> [bool; 8] {
/// Transforms a [bool; 8] into an u8 /// Transforms a [bool; 8] into an u8
fn vec_bit_to_u8(data: [bool; 8]) -> u8 { fn vec_bit_to_u8(data: [bool; 8]) -> u8 {
let mut result: u8 = 0; data.into_iter().fold(0, |result, bit| {
data.map(u8::from).iter().for_each(|&bit| { (result << 1) ^ u8::from(bit)
result <<= 1; })
result ^= bit;
});
result
} }
/// The reverse allows to write things on a more _humane_ way, but return a LE u8 /// The reverse allows to write things on a more _humane_ way, but return a LE u8
@ -458,22 +431,17 @@ fn partial_vec_to_u8_with_reverse(data: &[bool]) -> u8 {
/// UTF-16 Strings are give in pairs of bytes (u8), this converts them into an _actual_ string /// UTF-16 Strings are give in pairs of bytes (u8), this converts them into an _actual_ string
fn utf16_byte_pairs_to_string(data: &[u8]) -> String { fn utf16_byte_pairs_to_string(data: &[u8]) -> String {
let raw_utf16_composed = data let raw_utf16_composed = data
.chunks(2) .chunks_exact(2)
.collect::<Vec<&[u8]>>() .map(|chunk| u16::from_le_bytes([chunk[0], chunk[1]]))
.iter()
.map(|v| u16::from_le_bytes([*v.first().unwrap_or(&0), *v.get(1).unwrap_or(&0)]))
.collect::<Vec<u16>>(); .collect::<Vec<u16>>();
String::from_utf16(raw_utf16_composed.as_slice()) String::from_utf16_lossy(raw_utf16_composed.as_slice())
.unwrap()
.replace('\0', "")
} }
/// Gets the values from the slice and concatenates them /// Gets the values from the slice and concatenates them
fn get_and_concat_vec_bit(data: &[u8], get_values: &[usize]) -> Vec<bool> { fn get_and_concat_vec_bit(data: &[u8], get_values: &[usize]) -> Vec<bool> {
get_values get_values
.iter() .iter()
.map(|v| vec_bit(data[*v])) .flat_map(|v| vec_bit(data[*v]))
.collect::<Vec<[bool; 8]>>() .collect()
.concat()
} }

Loading…
Cancel
Save