Skip to content

Commit

Permalink
initial implementation
Browse files Browse the repository at this point in the history
Signed-off-by: Martin Kröning <martin.kroening@eonerc.rwth-aachen.de>
  • Loading branch information
mkroening committed May 24, 2024
1 parent 248f653 commit 000f86f
Show file tree
Hide file tree
Showing 9 changed files with 1,806 additions and 1 deletion.
1 change: 1 addition & 0 deletions .dockerignore
59 changes: 59 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: CI

on:
push:
pull_request:
merge_group:

env:
RUSTFLAGS: -Dwarnings
RUSTDOCFLAGS: -Dwarnings

jobs:
clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- run: cargo clippy --all-features

doc:
name: Doc
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- run: cargo doc --all-features

fmt:
name: Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
with:
components: rustfmt
- run: cargo fmt --all --check

test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- run: cargo test --all-features

test-s390x:
name: Test S390x
runs-on: ubuntu-latest
steps:
- uses: docker/setup-qemu-action@v3
with:
platforms: linux/s390x
- uses: docker/setup-buildx-action@v3
with:
platforms: linux/s390x
- uses: docker/build-push-action@v5
with:
platforms: linux/s390x
85 changes: 85 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 20 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
[package]
name = "endian-num"
version = "0.0.0"
authors = ["Martin Kröning <mkroening@posteo.net>"]
edition = "2021"
description = "Reserved."
description = "Byte-order-aware numeric types."
repository = "https://github.com/rust-osdev/endian-num"
license = "MIT OR Apache-2.0"
keywords = ["byte", "endian", "big-endian", "little-endian", "binary"]
categories = ["encoding", "rust-patterns", "no-std::no-alloc"]

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[dependencies]
bitflags = { version = "2", optional = true }
bytemuck = { version = "1", optional = true }
bytemuck_derive = { version = "1", optional = true }
zerocopy = { version = "0.7", optional = true, default-features = false }
zerocopy-derive = { version = "0.7", optional = true }

[features]
bitflags = ["dep:bitflags"]
bytemuck = ["dep:bytemuck", "dep:bytemuck_derive"]
linux-types = []
zerocopy = ["dep:zerocopy", "dep:zerocopy-derive"]
9 changes: 9 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM rust:latest
ENV CARGO_INCREMENTAL=0 \
CARGO_TERM_COLOR=always

WORKDIR /root/endian-num
COPY . .
RUN set -ex; \
cargo test --all-features; \
cargo clean
61 changes: 61 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# endian-num

[![Crates.io](https://img.shields.io/crates/v/endian-num)](https://crates.io/crates/endian-num)
[![docs.rs](https://img.shields.io/docsrs/endian-num)](https://docs.rs/endian-num)
[![CI](https://github.com/rust-osdev/endian-num/actions/workflows/ci.yml/badge.svg)](https://github.com/rust-osdev/endian-num/actions/workflows/ci.yml)

This crate provides the [`Be`] (big-endian) and [`Le`] (little-endian) byte-order-aware numeric types.

[`Be`]: https://docs.rs/endian-num/latest/endian_num/struct.Be.html
[`Le`]: https://docs.rs/endian-num/latest/endian_num/struct.Le.html

The core API looks _roughly_ like this (correspondingly for `Be`):

```rust
#[repr(transparent)]
pub struct<T> Le(pub T);

impl Le<T: Integer> {
pub const fn from_ne(n: T) -> Self;
pub const fn from_be(n: Be<T>) -> Self;

pub const fn to_ne(self) -> T;
pub const fn to_be(self) -> Be<T>;

pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()];
pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()];
pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()];

pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self;
pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self;
pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self;
}
```

The types also implement appropriate traits from [`core::cmp`], [`core::convert`], [`core::fmt`], and [`core::ops`] and provide additional helper methods for computations.

For API documentation, see the [docs].

[docs]: https://docs.rs/endian-num
[`core::cmp`]: https://doc.rust-lang.org/stable/core/cmp/index.html
[`core::convert`]: https://doc.rust-lang.org/stable/core/convert/index.html
[`core::fmt`]: https://doc.rust-lang.org/stable/core/fmt/index.html
[`core::ops`]: https://doc.rust-lang.org/stable/core/ops/index.html


## License

Licensed under either of

* Apache License, Version 2.0
([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license
([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)

at your option.

### Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.
2 changes: 2 additions & 0 deletions rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
group_imports = "StdExternalCrate"
imports_granularity = "Module"
67 changes: 67 additions & 0 deletions src/internal_macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//! Based on <https://github.com/rust-lang/rust/blob/1.78.0/library/core/src/internal_macros.rs>.
// implements the unary operator "op &T"
// based on "op T" where T is expected to be `Copy`able
macro_rules! forward_ref_unop {
(impl $Trait:ident, $method:ident for $T:ty) => {
impl $Trait for &$T {
type Output = <$T as $Trait>::Output;

#[inline]
#[track_caller]
fn $method(self) -> <$T as $Trait>::Output {
$Trait::$method(*self)
}
}
};
}

// implements binary operators "&T op Rhs", "T op &Rhs", "&T op &Rhs"
// based on "T op Rhs" where T and Rhs are expected to be `Copy`able
macro_rules! forward_ref_binop {
(impl $Trait:ident<$Rhs:ty>, $method:ident for $T:ty) => {
impl<'a> $Trait<$Rhs> for &'a $T {
type Output = <$T as $Trait<$Rhs>>::Output;

#[inline]
#[track_caller]
fn $method(self, rhs: $Rhs) -> <$T as $Trait<$Rhs>>::Output {
$Trait::$method(*self, rhs)
}
}

impl $Trait<&$Rhs> for $T {
type Output = <$T as $Trait<$Rhs>>::Output;

#[inline]
#[track_caller]
fn $method(self, rhs: &$Rhs) -> <$T as $Trait<$Rhs>>::Output {
$Trait::$method(self, *rhs)
}
}

impl $Trait<&$Rhs> for &$T {
type Output = <$T as $Trait<$Rhs>>::Output;

#[inline]
#[track_caller]
fn $method(self, rhs: &$Rhs) -> <$T as $Trait<$Rhs>>::Output {
$Trait::$method(*self, *rhs)
}
}
};
}

// implements "T op= &Rhs", based on "T op= Rhs"
// where Rhs is expected to be `Copy`able
macro_rules! forward_ref_op_assign {
(impl $Trait:ident<$Rhs:ty>, $method:ident for $T:ty) => {
impl $Trait<&$Rhs> for $T {
#[inline]
#[track_caller]
fn $method(&mut self, rhs: &$Rhs) {
$Trait::$method(self, *rhs);
}
}
};
}
Loading

0 comments on commit 000f86f

Please sign in to comment.