Move data crate to its own repo

I suspect that the `data` crate will get more review, use, and
contributors if it lives in its own repository, so move it to
casey/data.

type: removed
This commit is contained in:
Casey Rodarmor 2020-05-11 18:56:31 -07:00
parent 173c0e5ac5
commit c1c8d3cb89
No known key found for this signature in database
GPG Key ID: 556186B153EC6FE0
22 changed files with 6 additions and 575 deletions

81
Cargo.lock generated
View File

@ -181,15 +181,6 @@ dependencies = [
"time",
]
[[package]]
name = "claim"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b2e893ee68bf12771457cceea72497bc9cb7da404ec8a5311226d354b895ba4"
dependencies = [
"autocfg",
]
[[package]]
name = "clap"
version = "2.33.0"
@ -199,7 +190,7 @@ dependencies = [
"ansi_term 0.11.0",
"atty",
"bitflags",
"strsim 0.8.0",
"strsim",
"term_size",
"textwrap",
"unicode-width",
@ -257,66 +248,14 @@ dependencies = [
[[package]]
name = "ctor"
version = "0.1.13"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47c5e5ac752e18207b12e16b10631ae5f7f68f8805f335f9b817ead83d9ffce1"
checksum = "cf6b25ee9ac1995c54d7adb2eff8cfffb7260bc774fb63c601ec65467f43cd9d"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "darling"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim 0.9.3",
"syn",
]
[[package]]
name = "darling_macro"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72"
dependencies = [
"darling_core",
"quote",
"syn",
]
[[package]]
name = "data"
version = "0.1.0"
dependencies = [
"data-macros",
]
[[package]]
name = "data-macros"
version = "0.0.0"
dependencies = [
"darling",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "demo"
version = "0.0.0"
@ -510,12 +449,6 @@ dependencies = [
"quick-error",
]
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "idna"
version = "0.2.0"
@ -554,7 +487,6 @@ dependencies = [
"atty",
"bendy",
"chrono",
"claim",
"console",
"globset",
"ignore",
@ -578,7 +510,6 @@ dependencies = [
"structopt",
"strum",
"strum_macros",
"syn",
"tempfile",
"temptree",
"unicode-width",
@ -1097,12 +1028,6 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "strsim"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
[[package]]
name = "structopt"
version = "0.3.14"

View File

@ -36,7 +36,6 @@ snafu = "0.6.0"
static_assertions = "1.0.0"
strum = "0.18.0"
strum_macros = "0.18.0"
syn = "1.0.14"
tempfile = "3.0.0"
unicode-width = "0.1.0"
@ -61,7 +60,6 @@ version = "2.1.1"
features = ["serde"]
[dev-dependencies]
claim = "0.3.1"
temptree = "0.0.0"
[workspace]
@ -71,10 +69,4 @@ members = [
# run commands for demo animation
"bin/demo",
# data description language
"crates/data",
# data description language proc macros
"crates/data-macros",
]

View File

@ -27,6 +27,7 @@ pub(crate) enum Kind {
Reform,
Release,
Testing,
Removed,
}
impl Kind {
@ -43,6 +44,7 @@ impl Kind {
Self::Reform => "🎨",
Self::Release => "🔖",
Self::Testing => "",
Self::Removed => "",
}
}
@ -59,6 +61,7 @@ impl Kind {
Self::Reform => ":art:",
Self::Release => ":bookmark:",
Self::Testing => ":white_check_mark:",
Self::Removed => ":heavy_minus_sign:",
}
}
}

View File

@ -1,15 +0,0 @@
[package]
name = "data-macros"
version = "0.0.0"
authors = ["Casey Rodarmor <casey@rodarmor.com>"]
edition = "2018"
publish = false
[lib]
proc-macro = true
[dependencies]
darling = "0.10.2"
proc-macro2 = "1.0.12"
quote = "1.0.4"
syn = "1.0.18"

View File

@ -1,28 +0,0 @@
use crate::common::*;
pub(crate) trait Attribute: FromMeta {
type Item: syn::parse::Parse;
fn attribute(
attr: proc_macro::TokenStream,
item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
Self::inner(attr.into(), item.into()).tokens().into()
}
fn inner(attr: TokenStream, item: TokenStream) -> Result<TokenStream, Error> {
let args = Punctuated::<NestedMeta, token::Comma>::parse_terminated
.parse2(attr)?
.into_iter()
.collect();
Self::innermost(args, item)
}
fn innermost(args: Vec<NestedMeta>, item: TokenStream) -> Result<TokenStream, Error> {
let item = syn::parse2::<Self::Item>(item)?;
Self::from_list(&args)?.expand(item)
}
fn expand(&self, item: Self::Item) -> Result<TokenStream, Error>;
}

View File

@ -1,8 +0,0 @@
pub(crate) use darling::FromMeta;
pub(crate) use proc_macro2::TokenStream;
pub(crate) use quote::ToTokens;
pub(crate) use syn::{parse::Parser, punctuated::Punctuated, token, ItemTrait, NestedMeta};
pub(crate) use crate::{attribute::Attribute, tokens::Tokens};
pub(crate) use crate::{error::Error, table::Table};

View File

@ -1,28 +0,0 @@
use crate::common::*;
#[derive(Debug)]
pub(crate) enum Error {
Parse(darling::Error),
Syn(syn::Error),
}
impl From<darling::Error> for Error {
fn from(error: darling::Error) -> Error {
Error::Parse(error)
}
}
impl From<syn::Error> for Error {
fn from(error: syn::Error) -> Error {
Error::Syn(error)
}
}
impl Tokens for Error {
fn tokens(self) -> TokenStream {
match self {
Error::Parse(error) => error.write_errors(),
Error::Syn(error) => error.to_compile_error(),
}
}
}

View File

@ -1,19 +0,0 @@
use crate::common::*;
#[cfg(test)]
#[macro_use]
mod test;
mod attribute;
mod common;
mod error;
mod table;
mod tokens;
#[proc_macro_attribute]
pub fn table(
attr: proc_macro::TokenStream,
item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
Table::attribute(attr, item)
}

View File

@ -1,24 +0,0 @@
use crate::common::*;
#[derive(FromMeta)]
pub(crate) struct Table {}
impl Attribute for Table {
type Item = ItemTrait;
fn expand(&self, item: Self::Item) -> Result<TokenStream, Error> {
Ok(item.into_token_stream())
}
}
#[cfg(test)]
mod tests {
#[test]
fn empty() {
assert_attribute_expansion_eq!(
#[data::table]
trait Foo {},
trait Foo {}
);
}
}

View File

@ -1,66 +0,0 @@
use crate::common::*;
use syn::{Meta, MetaNameValue, NestedMeta};
macro_rules! assert_attribute_expansion_eq {
{
#[$meta:meta]
$item:item,
$($expansion:tt)*
} => {
{
let have = expand_attribute!(#[$meta] $item).unwrap().to_string();
let want = quote::quote!($($expansion)*).to_string();
assert_eq!(have, want);
}
}
}
macro_rules! expand_attribute {
{
#[$meta:meta]
$item:item
} => {
{
let meta = quote::quote!($meta);
let item = quote::quote!($item);
$crate::test::expand_attribute(meta, item)
}
}
}
pub(crate) fn expand_attribute(meta: TokenStream, item: TokenStream) -> Result<TokenStream, Error> {
let meta = syn::parse2::<Meta>(meta).unwrap();
let (path, args) = split_meta(meta);
match path.as_str() {
"data::table" => Table::innermost(args, item),
_ => panic!("attribute `{}` unknown", path),
}
}
fn split_meta(meta: Meta) -> (String, Vec<NestedMeta>) {
fn text(path: syn::Path) -> String {
let mut text = String::new();
if let Some(_) = path.leading_colon {
text.push_str("::");
}
for (i, segment) in path.segments.iter().enumerate() {
if i > 0 {
text.push_str("::");
}
text.push_str(&segment.ident.to_string());
}
text
}
match meta {
Meta::Path(path) => (text(path), Vec::new()),
Meta::List(syn::MetaList { path, nested, .. }) => (text(path), nested.into_iter().collect()),
Meta::NameValue(MetaNameValue { path, lit, .. }) => (text(path), vec![NestedMeta::Lit(lit)]),
}
}

View File

@ -1,20 +0,0 @@
use crate::common::*;
pub(crate) trait Tokens {
fn tokens(self) -> TokenStream;
}
impl Tokens for TokenStream {
fn tokens(self) -> TokenStream {
self
}
}
impl<T: Tokens, E: Tokens> Tokens for Result<T, E> {
fn tokens(self) -> TokenStream {
match self {
Ok(t) => t.tokens(),
Err(e) => e.tokens(),
}
}
}

View File

@ -1,8 +0,0 @@
[package]
name = "data"
version = "0.1.0"
authors = ["Casey Rodarmor <casey@rodarmor.com>"]
edition = "2018"
[dependencies.data-macros]
path = "../data-macros"

View File

@ -1,36 +0,0 @@
use crate::common::*;
pub(crate) struct Buffer {
layout: Layout,
alloc: *mut u8,
}
impl Buffer {
pub(crate) fn new<'a, T: Data<'a>>(contents: &[u8]) -> Buffer {
let layout = Layout::from_size_align(T::FIXED_SIZE, T::ALIGNMENT).unwrap();
let alloc = unsafe { alloc::alloc::alloc_zeroed(layout) };
let mut buffer = Buffer { layout, alloc };
buffer.deref_mut().copy_from_slice(contents);
buffer
}
}
impl Drop for Buffer {
fn drop(&mut self) {
unsafe { alloc::alloc::dealloc(self.alloc, self.layout) };
}
}
impl Deref for Buffer {
type Target = [u8];
fn deref(&self) -> &Self::Target {
unsafe { core::slice::from_raw_parts(self.alloc, self.layout.size()) }
}
}
impl DerefMut for Buffer {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { core::slice::from_raw_parts_mut(self.alloc, self.layout.size()) }
}
}

View File

@ -1,26 +0,0 @@
pub(crate) use core::{result, str::Utf8Error};
pub(crate) use crate::error::Error;
pub(crate) use crate::data::Data;
pub(crate) type Result<T, E = Error> = result::Result<T, E>;
#[cfg(test)]
mod test {
pub(crate) extern crate alloc;
pub(crate) use core::{
fmt::Debug,
ops::{Deref, DerefMut},
};
pub(crate) use alloc::{alloc::Layout, vec::Vec};
pub(crate) use crate::buffer::Buffer;
pub(crate) use crate::data_test::DataTest;
}
#[cfg(test)]
pub(crate) use test::*;

View File

@ -1,27 +0,0 @@
use crate::common::*;
pub trait Data<'a>: Sized + 'a {
const FIXED_SIZE: usize;
const ALIGNMENT: usize;
fn load(buffer: &'a [u8]) -> Result<Self>;
fn store(&self, buffer: &mut [u8]) -> Result<()>;
fn check(buffer: &'a [u8]) -> Result<()> {
let have = buffer.len();
let want = Self::FIXED_SIZE;
if have < want {
return Err(Error::Size { have, want });
}
let alignment = Self::ALIGNMENT;
let offset = buffer.as_ptr().align_offset(alignment);
if offset != 0 {
return Err(Error::Alignment { alignment, offset });
}
Ok(())
}
}

View File

@ -1,38 +0,0 @@
use crate::common::*;
pub trait DataTest<'a>: Data<'a> + PartialEq + Debug + Default {
fn round_trip(self, encoded: &'a [u8]) -> Result<()> {
let mut buffer = Vec::<u8>::with_capacity(Self::FIXED_SIZE);
buffer.resize(Self::FIXED_SIZE, 0);
self.store(&mut buffer)?;
assert_eq!(buffer, encoded);
let decoded = Self::load(&encoded)?;
assert_eq!(self, decoded);
Ok(())
}
fn error_test(buffer: &'a mut [u8]) {
let want = Self::FIXED_SIZE;
let have = Self::FIXED_SIZE - 1;
assert_eq!(buffer.len(), want);
let short_buffer = &mut buffer[..have];
assert_eq!(
Self::default().store(short_buffer),
Err(Error::Size { have, want })
);
assert_eq!(Self::load(short_buffer), Err(Error::Size { have, want }));
}
}
impl<'a, T: Data<'a> + PartialEq + Debug + Default> DataTest<'a> for T {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[should_panic]
fn round_trip_test() {
0u8.round_trip(&[1]).ok();
}
}

View File

@ -1,8 +0,0 @@
use crate::common::*;
#[derive(Debug, PartialEq)]
pub enum Error {
Alignment { alignment: usize, offset: usize },
UnicodeDecode { source: Utf8Error },
Size { have: usize, want: usize },
}

View File

@ -1,17 +0,0 @@
#![no_std]
mod common;
mod data;
mod error;
mod u16;
mod u8;
#[cfg(test)]
mod buffer;
#[cfg(test)]
mod data_test;
pub use data_macros::table;
pub use crate::{data::Data, error::Error};

View File

@ -1,38 +0,0 @@
use crate::common::*;
impl<'a> Data<'a> for u16 {
const ALIGNMENT: usize = 2;
const FIXED_SIZE: usize = 2;
fn load(buffer: &'a [u8]) -> Result<Self> {
Self::check(buffer)?;
Ok(u16::from_le_bytes([buffer[0], buffer[1]]))
}
fn store(&self, buffer: &mut [u8]) -> Result<()> {
Self::check(buffer)?;
let bytes = self.to_le_bytes();
buffer.copy_from_slice(&bytes);
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn u16_round_trip() -> Result<()> {
0u16.round_trip(&Buffer::new::<u16>(&[0, 0]))?;
1u16.round_trip(&Buffer::new::<u16>(&[1, 0]))?;
255u16.round_trip(&Buffer::new::<u16>(&[255, 0]))?;
256u16.round_trip(&Buffer::new::<u16>(&[0, 1]))?;
u16::max_value().round_trip(&Buffer::new::<u16>(&[0xFF, 0xFF]))?;
Ok(())
}
#[test]
fn u16_errors() {
u16::error_test(&mut Buffer::new::<u16>(&[0, 0]));
}
}

View File

@ -1,35 +0,0 @@
use crate::common::*;
impl<'a> Data<'a> for u8 {
const ALIGNMENT: usize = 1;
const FIXED_SIZE: usize = 1;
fn load(buffer: &'a [u8]) -> Result<Self> {
Self::check(buffer)?;
Ok(buffer[0])
}
fn store(&self, buffer: &mut [u8]) -> Result<()> {
Self::check(buffer)?;
buffer[0] = *self;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn u8_round_trip() -> Result<()> {
0u8.round_trip(&[0])?;
1u8.round_trip(&[1])?;
255u8.round_trip(&[255])?;
Ok(())
}
#[test]
fn u8_errors() {
u8::error_test(&mut Buffer::new::<u8>(&[0]));
}
}

View File

@ -1,48 +0,0 @@
#[cfg(aspirational)]
mod aspirational {
#[data::structure]
struct Manifest {
magic_number: [u8; 8], // IMDL + 4 bytes that aren't valid UTF-8
version: Version, // 256.256.256
}
#[data::structure]
struct Version {
major: u64,
minor: u64,
patch: u64,
}
#[data::table]
struct Manifest;
#[data::table_impl]
impl Manifest {
fn files(&self) -> Slice<Hash>;
fn directory(&self) -> Directory;
}
#[data::structure]
struct Directory {
records: Slice<Record>,
}
#[data::structure]
struct Record {
name: &str,
node: Node,
}
#[data::enumeration]
enum Node {
Directory(Directory),
File(u64),
}
#[data::structure]
struct Hash {
bytes: [u8; 32],
}
}