Skip to content

Commit

Permalink
Add initial dyn slice implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
tomBoddaert committed Jul 11, 2023
0 parents commit 64960c1
Show file tree
Hide file tree
Showing 10 changed files with 474 additions and 0 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Rust

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

env:
CARGO_TERM_COLOR: always

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Clippy
run: |
cargo clippy --all-targets
cargo clippy --no-default-features
- name: Build
run: |
cargo build --verbose
cargo build --verbose --no-default-features
- name: Run tests
run: cargo test
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Cargo.lock
/target
22 changes: 22 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "dyn-slice"
version = "1.0.0-alpha.0"
authors = ["Tom Boddaert"]
edition = "2021"
description = "&dyn [Trait] implementation, inspired by a Reddit thread."
readme = "README.md"
homepage = "https://github.com/tomBoddaert/dyn-slice/"
repository = "https://github.com/tomBoddaert/dyn-slice/"
license = "MIT OR Apache-2.0"
keywords = ["dyn", "slice", "traits"]
categories = ["data-structures", "no-std"]

[lib]
name = "dyn_slice"
edition = "2021"
path = "lib/lib.rs"
crate-type = ["lib"]

[features]
default = ["std"]
std = []
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[![Rust](https://github.com/tomBoddaert/dyn-slice/actions/workflows/rust.yml/badge.svg?event=push)](https://github.com/tomBoddaert/dyn-slice/actions/workflows/rust.yml)

# Dyn-Slice

An implementation for a `&dyn [Trait]`-like reference, inspired by a [Reddit thread](https://www.reddit.com/r/rust/comments/14i08gz/dyn_slices).

## Warning

DO NOT USE THIS IN PRODUCTION (or any important) CODE: IT IS A PROOF OF CONCEPT AND PROBABLY HAS MANY BUGS.

With that said, feel free to use it in code that does not have to be reliable and to send pull requests to fix some of the bugs.

## License

[Dyn-Slice](https://github.com/tomBoddaert/dyn-slice) is dual-licensed under either the Apache License Version 2.0 or MIT license at your option.
56 changes: 56 additions & 0 deletions examples/custom_generic_trait.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#![feature(ptr_metadata, trait_alias, pointer_byte_offsets)]

use dyn_slice::declare_dyn_slice;

pub trait MyTrait<T> {
fn to_t(&self) -> T;
fn add(&self, rhs: T) -> T;
}

macro_rules! impl_my_trait {
( $ty:ty, $to:ty ) => {
impl MyTrait<$to> for $ty {
fn to_t(&self) -> $to {
u64::from(*self)
}

fn add(&self, rhs: $to) -> $to {
self.to_t() + rhs
}
}
};
}

impl_my_trait!(u8, u64);
impl_my_trait!(u16, u64);

declare_dyn_slice!(<T>, MyTrait:<T>, my_trait_dyn_slice);
use my_trait_dyn_slice::*;

declare_dyn_slice!(MyTrait:<u64>, my_trait_u64_dyn_slice);
#[allow(unused_imports)]
use my_trait_u64_dyn_slice::{DynSlice as DynSliceMTU64, Iter as IterMTU64};

fn main() {
let array: [u8; 4] = [1, 2, 3, 4];

let dyn_slice = DynSlice::<'_, u64>::new(&array);

let first = dyn_slice.first().map(MyTrait::<u64>::to_t);
let last = dyn_slice.last().map(MyTrait::<u64>::to_t);
println!("1: first: {first:?}, last: {last:?}");

let array2: [u16; 3] = [5, 6, 7];

let dyn_slice2 = DynSlice::<'_, u64>::new(&array2);

let first = dyn_slice2.first().map(MyTrait::<u64>::to_t);
let last = dyn_slice2.last().map(MyTrait::<u64>::to_t);

println!("2: first: {first:?}, last: {last:?}\n");

let iter = dyn_slice.iter().zip(dyn_slice2.iter());
for (i, (a, b)) in iter.enumerate() {
println!("sum {}: {}", i + 1, a.add(b.to_t()));
}
}
53 changes: 53 additions & 0 deletions examples/custom_trait.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#![feature(ptr_metadata, trait_alias, pointer_byte_offsets)]

use dyn_slice::declare_dyn_slice;

pub trait MyTrait {
fn to_u64(&self) -> u64;
fn add(&self, rhs: u64) -> u64;
}

macro_rules! impl_my_trait {
( $ty:ty ) => {
impl MyTrait for $ty {
fn to_u64(&self) -> u64 {
u64::from(*self)
}

fn add(&self, rhs: u64) -> u64 {
self.to_u64() + rhs
}
}
};
}

impl_my_trait!(u8);
impl_my_trait!(u16);

declare_dyn_slice!(MyTrait, my_trait_dyn_slice);
use my_trait_dyn_slice::*;

fn main() {
let array: [u8; 4] = [1, 2, 3, 4];

let dyn_slice = DynSlice::new(&array);

let first = dyn_slice.first().map(MyTrait::to_u64);
let last = dyn_slice.last().map(MyTrait::to_u64);

println!("1: first: {first:?}, last: {last:?}");

let array2: [u16; 3] = [5, 6, 7];

let dyn_slice2 = DynSlice::new(&array2);

let first = dyn_slice2.first().map(MyTrait::to_u64);
let last = dyn_slice2.last().map(MyTrait::to_u64);

println!("2: first: {first:?}, last: {last:?}\n");

let iter = dyn_slice.iter().zip(dyn_slice2.iter());
for (i, (a, b)) in iter.enumerate() {
println!("sum {}: {}", i + 1, a.add(b.to_u64()));
}
}
23 changes: 23 additions & 0 deletions examples/display.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#![feature(ptr_metadata, trait_alias, pointer_byte_offsets)]

use std::fmt::Display;

use dyn_slice::declare_dyn_slice;

declare_dyn_slice!(Display, display_dyn_slice);
use display_dyn_slice::*;

fn main() {
let array: [u8; 4] = [1, 2, 3, 4];

let dyn_slice = DynSlice::new(&array);

let array2: [i16; 3] = [5, 6, 7];

let dyn_slice2 = DynSlice::new(&array2);

let iter = dyn_slice.iter().chain(dyn_slice2.iter());
for n in iter {
println!("{n}");
}
}

0 comments on commit 64960c1

Please sign in to comment.