mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-08 19:34:27 +00:00
Turned various functions in util and io const.
Added missing `Sub` and `SubAssign` implementations to `io::address::Real`. Added `from_u64` and `as_u64` to both address types in `io`.
This commit is contained in:
@@ -15,23 +15,28 @@ use crate::{
|
||||
pub struct Data(u64);
|
||||
|
||||
impl Data {
|
||||
/// Constructs a data address from it's `u64` representation
|
||||
/// Creates a data address from a `u64`
|
||||
#[must_use]
|
||||
pub const fn from_u64(address: u64) -> Self {
|
||||
Self(address)
|
||||
}
|
||||
|
||||
/// Returns this address as a `u64`
|
||||
#[must_use]
|
||||
pub const fn as_u64(self) -> u64 {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// Returns the sector associated with this address
|
||||
#[must_use]
|
||||
#[allow(clippy::integer_division)] // We want to get the whole division
|
||||
pub fn sector(self) -> u64 {
|
||||
u64::from(self) / Real::DATA_BYTE_SIZE
|
||||
pub const fn sector(self) -> u64 {
|
||||
self.as_u64() / Real::DATA_BYTE_SIZE
|
||||
}
|
||||
|
||||
/// Returns the offset into the data section of this address
|
||||
#[must_use]
|
||||
pub fn offset(self) -> u64 {
|
||||
u64::from(self) % Real::DATA_BYTE_SIZE
|
||||
pub const fn offset(self) -> u64 {
|
||||
self.as_u64() % Real::DATA_BYTE_SIZE
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,28 +30,39 @@ impl Real {
|
||||
}
|
||||
|
||||
impl Real {
|
||||
/// Creates a real address from a `u64`
|
||||
#[must_use]
|
||||
pub const fn from_u64(address: u64) -> Self {
|
||||
Self(address)
|
||||
}
|
||||
|
||||
/// Returns this address as a `u64`
|
||||
#[must_use]
|
||||
pub const fn as_u64(self) -> u64 {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// Returns the real sector associated with this address
|
||||
#[must_use]
|
||||
#[allow(clippy::integer_division)] // We want to get the whole division
|
||||
pub fn sector(self) -> u64 {
|
||||
u64::from(self) / Self::SECTOR_BYTE_SIZE
|
||||
pub const fn sector(self) -> u64 {
|
||||
self.as_u64() / Self::SECTOR_BYTE_SIZE
|
||||
}
|
||||
|
||||
/// Returns the offset into the sector of this address
|
||||
#[must_use]
|
||||
pub fn offset(self) -> u64 {
|
||||
u64::from(self) % Self::SECTOR_BYTE_SIZE
|
||||
pub const fn offset(self) -> u64 {
|
||||
self.as_u64() % Self::SECTOR_BYTE_SIZE
|
||||
}
|
||||
|
||||
/// Returns the address of the end of the data section in this sector.
|
||||
#[must_use]
|
||||
pub fn data_section_end(self) -> Self {
|
||||
pub const fn data_section_end(self) -> Self {
|
||||
// Get the sector
|
||||
let real_sector = self.sector();
|
||||
|
||||
// The end of the real data section is after the header and data sections
|
||||
#[rustfmt::skip]
|
||||
Self::from(
|
||||
Self::from_u64(
|
||||
Self::SECTOR_BYTE_SIZE * real_sector + // Beginning of sector
|
||||
Self::HEADER_BYTE_SIZE + // Skip Header
|
||||
Self:: DATA_BYTE_SIZE, // Skip Data
|
||||
@@ -60,9 +71,11 @@ impl Real {
|
||||
|
||||
/// Checks if this address is within the real data section
|
||||
#[must_use]
|
||||
pub fn in_data_section(self) -> bool {
|
||||
pub const fn in_data_section(self) -> bool {
|
||||
// If our offset is within the data range
|
||||
Self::DATA_RANGE.contains(&self.offset())
|
||||
// TODO: Replace with `Self::DATA_RANGE.contains(&self.offset())` once it's `const`.
|
||||
let offset = self.offset();
|
||||
offset >= Self::DATA_RANGE.start && offset < Self::DATA_RANGE.end
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +95,25 @@ impl std::ops::AddAssign<i64> for Real {
|
||||
}
|
||||
}
|
||||
|
||||
// Real - Offset
|
||||
impl std::ops::Sub<i64> for Real {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(self, offset: i64) -> Self {
|
||||
if offset == i64::MIN {
|
||||
panic!("Unable to offset `i64::MIN`")
|
||||
}
|
||||
Self::from(signed_offset(self.into(), -offset))
|
||||
}
|
||||
}
|
||||
|
||||
// Real += Offset
|
||||
impl std::ops::SubAssign<i64> for Real {
|
||||
fn sub_assign(&mut self, offset: i64) {
|
||||
*self = *self - offset;
|
||||
}
|
||||
}
|
||||
|
||||
// Real - Real
|
||||
impl std::ops::Sub<Real> for Real {
|
||||
type Output = i64;
|
||||
|
||||
@@ -36,7 +36,9 @@
|
||||
stmt_expr_attributes,
|
||||
unwrap_infallible,
|
||||
external_doc,
|
||||
format_args_capture
|
||||
format_args_capture,
|
||||
const_fn,
|
||||
const_panic
|
||||
)]
|
||||
// Lints
|
||||
#![warn(clippy::restriction, clippy::pedantic, clippy::nursery)]
|
||||
@@ -72,8 +74,8 @@
|
||||
// In the future, this lint should be removed globally and only enabled for modules which
|
||||
// actually require the use of it.
|
||||
#![allow(clippy::module_inception, clippy::module_name_repetitions)]
|
||||
// Banning arithmetic is too strict for this project
|
||||
#![allow(clippy::integer_arithmetic)]
|
||||
// We use integer arithmetic and operations with the correct intent
|
||||
#![allow(clippy::integer_arithmetic, clippy::integer_division)]
|
||||
// We prefer using match ergonomic where possible
|
||||
#![allow(clippy::pattern_type_mismatch)]
|
||||
// False positives:
|
||||
|
||||
@@ -21,7 +21,7 @@ pub use array_split::{array_split, array_split_mut};
|
||||
/// If the result would not fit into a `i64`, a panic occurs.
|
||||
#[allow(clippy::as_conversions)] // We check every operation
|
||||
#[allow(clippy::panic)] // Rust panics on failed arithmetic operations by default
|
||||
pub fn abs_diff(a: u64, b: u64) -> i64 {
|
||||
pub const fn abs_diff(a: u64, b: u64) -> i64 {
|
||||
let diff = if a > b { a - b } else { b - a };
|
||||
|
||||
if diff > i64::MAX as u64 {
|
||||
@@ -42,11 +42,14 @@ pub fn abs_diff(a: u64, b: u64) -> i64 {
|
||||
#[allow(clippy::as_conversions)] // We check every operation
|
||||
#[allow(clippy::panic)] // Rust panics on failed arithmetic operations by default
|
||||
#[allow(clippy::cast_sign_loss)] // We've verify it's positive
|
||||
pub fn signed_offset(a: u64, b: i64) -> u64 {
|
||||
pub const fn signed_offset(a: u64, b: i64) -> u64 {
|
||||
// If `b` is positive, check for overflows. Else check for underflows
|
||||
if b > 0 {
|
||||
// Note: Cast is safe, as a positive `i64` fits into a `u64`.
|
||||
a.checked_add(b as u64).expect("Overflow evaluating `u64 + i64`")
|
||||
match a.checked_add(b as u64) {
|
||||
Some(res) => res,
|
||||
None => panic!("Overflow evaluating `u64 + i64`"),
|
||||
}
|
||||
} else {
|
||||
// Note: On `i64::MIN`, `-b` would overflow
|
||||
if b == i64::MIN || a < (-b) as u64 {
|
||||
|
||||
Reference in New Issue
Block a user