mirror of
https://github.com/nushell/nushell.git
synced 2024-11-23 00:43:33 +01:00
Add doc comments and other trait implementations
This commit is contained in:
parent
6e54c16468
commit
33b28ff9b3
@ -7,37 +7,41 @@ use std::{
|
|||||||
fmt,
|
fmt,
|
||||||
iter::Sum,
|
iter::Sum,
|
||||||
ops::{Add, Mul, Neg, Sub},
|
ops::{Add, Mul, Neg, Sub},
|
||||||
|
str::FromStr,
|
||||||
};
|
};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
/// A signed number of bytes.
|
||||||
|
///
|
||||||
|
/// [`Filesize`] is a wrapper around [`i64`]. Whereas [`i64`] is a dimensionless value, [`Filesize`] represents a
|
||||||
|
/// numerical value with a dimensional unit (byte).
|
||||||
|
///
|
||||||
|
/// A [`Filesize`] can be created from an [`i64`] using [`Filesize::new`] or the `From` or `Into` trait implementations.
|
||||||
|
/// To get the underlying [`i64`] value, use [`Filesize::get`] or the `From` or `Into` trait implementations.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[serde(transparent)]
|
#[serde(transparent)]
|
||||||
pub struct Filesize(i64);
|
pub struct Filesize(i64);
|
||||||
|
|
||||||
impl Filesize {
|
impl Filesize {
|
||||||
|
/// A [`Filesize`] of 0 bytes.
|
||||||
pub const ZERO: Self = Self(0);
|
pub const ZERO: Self = Self(0);
|
||||||
|
|
||||||
|
/// The smallest possible [`Filesize`] value.
|
||||||
|
pub const MIN: Self = Self(i64::MIN);
|
||||||
|
|
||||||
|
/// The largest possible [`Filesize`] value.
|
||||||
|
pub const MAX: Self = Self(i64::MAX);
|
||||||
|
|
||||||
|
/// Create a new [`Filesize`] from a [`i64`] number of bytes.
|
||||||
pub const fn new(bytes: i64) -> Self {
|
pub const fn new(bytes: i64) -> Self {
|
||||||
Self(bytes)
|
Self(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn get(&self) -> i64 {
|
/// Creates a [`Filesize`] from a signed multiple of a [`FilesizeUnit`].
|
||||||
self.0
|
///
|
||||||
}
|
/// If the resulting number of bytes calculated by `value * unit.as_bytes()` overflows an
|
||||||
|
/// [`i64`], then `None` is returned.
|
||||||
pub const fn is_positive(self) -> bool {
|
|
||||||
self.0.is_positive()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn is_negative(self) -> bool {
|
|
||||||
self.0.is_negative()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn signum(self) -> Self {
|
|
||||||
Self(self.0.signum())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn from_unit(value: i64, unit: FilesizeUnit) -> Option<Self> {
|
pub const fn from_unit(value: i64, unit: FilesizeUnit) -> Option<Self> {
|
||||||
if let Some(bytes) = value.checked_mul(unit.as_bytes() as i64) {
|
if let Some(bytes) = value.checked_mul(unit.as_bytes() as i64) {
|
||||||
Some(Self(bytes))
|
Some(Self(bytes))
|
||||||
@ -45,6 +49,29 @@ impl Filesize {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the underlying [`i64`] number of bytes in a [`Filesize`].
|
||||||
|
pub const fn get(&self) -> i64 {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if a [`Filesize`] is positive and false if it is zero or negative.
|
||||||
|
pub const fn is_positive(self) -> bool {
|
||||||
|
self.0.is_positive()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if a [`Filesize`] is negative and false if it is zero or positive.
|
||||||
|
pub const fn is_negative(self) -> bool {
|
||||||
|
self.0.is_negative()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a [`Filesize`] representing the sign of `self`.
|
||||||
|
/// - 0 if the filesize is zero
|
||||||
|
/// - 1 if the filesize is positive
|
||||||
|
/// - -1 if the filesize is negative
|
||||||
|
pub const fn signum(self) -> Self {
|
||||||
|
Self(self.0.signum())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<i64> for Filesize {
|
impl From<i64> for Filesize {
|
||||||
@ -75,6 +102,7 @@ impl TryFrom<Filesize> for u64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The error type returned when a checked conversion from a floating point type fails.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Error)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Error)]
|
||||||
pub struct TryFromFloatError(());
|
pub struct TryFromFloatError(());
|
||||||
|
|
||||||
@ -230,24 +258,45 @@ impl fmt::Display for Filesize {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// All the possible filesize units for a [`Filesize`].
|
||||||
|
///
|
||||||
|
/// This type contains both units with metric (SI) decimal prefixes which are powers of 10 (e.g., KB = 1000 bytes)
|
||||||
|
/// and units with binary prefixes which are powers of 2 (e.g., KiB = 1024 bytes).
|
||||||
|
///
|
||||||
|
/// The number of bytes in a [`FilesizeUnit`] can be obtained using
|
||||||
|
/// [`as_bytes`](FilesizeUnit::as_bytes).
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub enum FilesizeUnit {
|
pub enum FilesizeUnit {
|
||||||
|
/// One byte
|
||||||
B,
|
B,
|
||||||
|
/// Kilobyte = 1000 bytes
|
||||||
KB,
|
KB,
|
||||||
|
/// Megabyte = 10<sup>6</sup> bytes
|
||||||
MB,
|
MB,
|
||||||
|
/// Gigabyte = 10<sup>9</sup> bytes
|
||||||
GB,
|
GB,
|
||||||
|
/// Terabyte = 10<sup>12</sup> bytes
|
||||||
TB,
|
TB,
|
||||||
|
/// Petabyte = 10<sup>15</sup> bytes
|
||||||
PB,
|
PB,
|
||||||
|
/// Exabyte = 10<sup>18</sup> bytes
|
||||||
EB,
|
EB,
|
||||||
|
/// Kibibyte = 1024 bytes
|
||||||
KiB,
|
KiB,
|
||||||
|
/// Mebibyte = 2<sup>20</sup> bytes
|
||||||
MiB,
|
MiB,
|
||||||
|
/// Gibibyte = 2<sup>30</sup> bytes
|
||||||
GiB,
|
GiB,
|
||||||
|
/// Tebibyte = 2<sup>40</sup> bytes
|
||||||
TiB,
|
TiB,
|
||||||
|
/// Pebibyte = 2<sup>50</sup> bytes
|
||||||
PiB,
|
PiB,
|
||||||
|
/// Exbibyte = 2<sup>60</sup> bytes
|
||||||
EiB,
|
EiB,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FilesizeUnit {
|
impl FilesizeUnit {
|
||||||
|
/// Returns the number of bytes in a [`FilesizeUnit`].
|
||||||
pub const fn as_bytes(&self) -> u64 {
|
pub const fn as_bytes(&self) -> u64 {
|
||||||
match self {
|
match self {
|
||||||
Self::B => 1,
|
Self::B => 1,
|
||||||
@ -257,19 +306,33 @@ impl FilesizeUnit {
|
|||||||
Self::TB => 10_u64.pow(12),
|
Self::TB => 10_u64.pow(12),
|
||||||
Self::PB => 10_u64.pow(15),
|
Self::PB => 10_u64.pow(15),
|
||||||
Self::EB => 10_u64.pow(18),
|
Self::EB => 10_u64.pow(18),
|
||||||
Self::KiB => 1 << 10,
|
Self::KiB => 2_u64.pow(10),
|
||||||
Self::MiB => 1 << 20,
|
Self::MiB => 2_u64.pow(20),
|
||||||
Self::GiB => 1 << 30,
|
Self::GiB => 2_u64.pow(30),
|
||||||
Self::TiB => 1 << 40,
|
Self::TiB => 2_u64.pow(40),
|
||||||
Self::PiB => 1 << 50,
|
Self::PiB => 2_u64.pow(50),
|
||||||
Self::EiB => 1 << 60,
|
Self::EiB => 2_u64.pow(60),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert a [`FilesizeUnit`] to a [`Filesize`].
|
||||||
|
///
|
||||||
|
/// To create a [`Filesize`] from a multiple of a [`FilesizeUnit`] use [`Filesize::from_unit`].
|
||||||
pub const fn as_filesize(&self) -> Filesize {
|
pub const fn as_filesize(&self) -> Filesize {
|
||||||
Filesize::new(self.as_bytes() as i64)
|
Filesize::new(self.as_bytes() as i64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the abbreviated unit for a [`FilesizeUnit`] as a [`str`].
|
||||||
|
///
|
||||||
|
/// The abbreviated unit is exactly the same as the enum case name in Rust code.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # use nu_protocol::FilesizeUnit;
|
||||||
|
/// assert_eq!(FilesizeUnit::B.as_str(), "B");
|
||||||
|
/// assert_eq!(FilesizeUnit::KB.as_str(), "KB");
|
||||||
|
/// assert_eq!(FilesizeUnit::KiB.as_str(), "KiB");
|
||||||
|
/// ```
|
||||||
pub const fn as_str(&self) -> &'static str {
|
pub const fn as_str(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Self::B => "B",
|
Self::B => "B",
|
||||||
@ -288,6 +351,9 @@ impl FilesizeUnit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if a [`FilesizeUnit`] has a metric (SI) decimal prefix (a power of 10).
|
||||||
|
///
|
||||||
|
/// Note that this returns `true` for [`FilesizeUnit::B`] as well.
|
||||||
pub const fn is_decimal(&self) -> bool {
|
pub const fn is_decimal(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::B | Self::KB | Self::MB | Self::GB | Self::TB | Self::PB | Self::EB => true,
|
Self::B | Self::KB | Self::MB | Self::GB | Self::TB | Self::PB | Self::EB => true,
|
||||||
@ -295,6 +361,9 @@ impl FilesizeUnit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if a [`FilesizeUnit`] has a binary prefix (a power of 2).
|
||||||
|
///
|
||||||
|
/// Note that this returns `true` for [`FilesizeUnit::B`] as well.
|
||||||
pub const fn is_binary(&self) -> bool {
|
pub const fn is_binary(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::KB | Self::MB | Self::GB | Self::TB | Self::PB | Self::EB => false,
|
Self::KB | Self::MB | Self::GB | Self::TB | Self::PB | Self::EB => false,
|
||||||
@ -303,6 +372,48 @@ impl FilesizeUnit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<FilesizeUnit> for Filesize {
|
||||||
|
fn from(unit: FilesizeUnit) -> Self {
|
||||||
|
unit.as_filesize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An error returned when failing to parse a [`FilesizeUnit`].
|
||||||
|
///
|
||||||
|
/// This occurs when the string being parsed does not exactly match the name of one of the
|
||||||
|
/// enum cases in [`FilesizeUnit`].
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Error)]
|
||||||
|
pub struct ParseFilesizeUnitError(());
|
||||||
|
|
||||||
|
impl fmt::Display for ParseFilesizeUnitError {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(fmt, "invalid filesize unit")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for FilesizeUnit {
|
||||||
|
type Err = ParseFilesizeUnitError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
Ok(match s {
|
||||||
|
"B" => Self::B,
|
||||||
|
"KB" => Self::KB,
|
||||||
|
"MB" => Self::MB,
|
||||||
|
"GB" => Self::GB,
|
||||||
|
"TB" => Self::TB,
|
||||||
|
"PB" => Self::PB,
|
||||||
|
"EB" => Self::EB,
|
||||||
|
"KiB" => Self::KiB,
|
||||||
|
"MiB" => Self::MiB,
|
||||||
|
"GiB" => Self::GiB,
|
||||||
|
"TiB" => Self::TiB,
|
||||||
|
"PiB" => Self::PiB,
|
||||||
|
"EiB" => Self::EiB,
|
||||||
|
_ => return Err(ParseFilesizeUnitError(())),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for FilesizeUnit {
|
impl fmt::Display for FilesizeUnit {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
self.as_str().fmt(f)
|
self.as_str().fmt(f)
|
||||||
|
Loading…
Reference in New Issue
Block a user