ext4_view/label.rs
1// Copyright 2025 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use crate::format::{BytesDisplay, format_bytes_debug};
10use core::fmt::{self, Debug, Formatter};
11use core::str::Utf8Error;
12
13/// Filesystem label.
14///
15/// The label is at most 16 bytes, and may contain null bytes. The
16/// encoding is not specified.
17#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
18pub struct Label([u8; 16]);
19
20impl Label {
21 /// Create a label from raw bytes.
22 #[must_use]
23 pub const fn new(bytes: [u8; 16]) -> Self {
24 Self(bytes)
25 }
26
27 /// Convert the label to a UTF-8 string, if possible.
28 ///
29 /// The first null byte, and any following bytes, are excluded from
30 /// the conversion.
31 pub fn to_str(&self) -> Result<&str, Utf8Error> {
32 core::str::from_utf8(self.as_bytes_up_to_first_null())
33 }
34
35 /// Get the raw bytes of the label. This may include null bytes.
36 #[must_use]
37 pub const fn as_bytes(&self) -> &[u8; 16] {
38 &self.0
39 }
40
41 /// Get the bytes up to the first null, or all of the bytes if there
42 /// is no null byte.
43 #[must_use]
44 fn as_bytes_up_to_first_null(&self) -> &[u8] {
45 if let Some(index) = self.0.iter().position(|c| *c == 0) {
46 &self.0[..index]
47 } else {
48 &self.0
49 }
50 }
51
52 /// Get an object that implements [`Display`] to allow conveniently
53 /// printing labels that may or may not be valid UTF-8. Non-UTF-8
54 /// characters will be replaced with '�'.
55 ///
56 /// Null bytes are not included.
57 ///
58 /// [`Display`]: core::fmt::Display
59 pub fn display(&self) -> BytesDisplay {
60 BytesDisplay(self.as_bytes_up_to_first_null())
61 }
62}
63
64impl Debug for Label {
65 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
66 format_bytes_debug(self.as_bytes_up_to_first_null(), f)
67 }
68}