combine crates to workspace

This commit is contained in:
Florian Stecker 2024-02-28 00:57:20 -05:00
parent e853f8bc46
commit bc852d6b6a
18 changed files with 243 additions and 42 deletions

View File

@ -1,10 +1,8 @@
[package]
name = "parsebtrfs"
version = "0.1.0"
edition = "2021"
[workspace]
resolver = "2"
[dependencies]
binparse_derive = { path = "../binparse_derive" }
maud = "0.26.0"
memmap2 = "0.7.1"
rouille = "3.6.2"
members = [
"btrfs_explorer_bin",
"btrfs_parse_derive",
"btrfs_explorer",
]

View File

@ -0,0 +1,9 @@
[package]
name = "btrfs_explorer"
version = "0.1.0"
edition = "2021"
[dependencies]
btrfs_parse_derive = { path = "../btrfs_parse_derive" }
maud = "0.26.0"
rouille = "3.6.2"

View File

@ -0,0 +1,12 @@
[package]
name = "btrfs_explorer_bin"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
btrfs_explorer = { path = "../btrfs_explorer" }
memmap2 = "0.7.1"
maud = "0.26.0"
rouille = "3.6.2"

View File

@ -3,7 +3,7 @@ use std::{
};
use memmap2::{Mmap, MmapOptions};
use rouille::{Request, Response, router};
use parsebtrfs::{
use btrfs_explorer::{
btrfs_structs::{TreeID, Value::Extent, Value::BlockGroup, NODE_SIZE, ItemType},
btrfs_lookup::Tree,
addrmap::AddressMap,
@ -41,15 +41,15 @@ fn main() -> Result<(), MainError> {
(GET) ["/"] =>
http_main_boxes(&image, request),
(GET) ["/root"] =>
parsebtrfs::http_tree::http_root(&image, None, request),
btrfs_explorer::http_tree::http_root(&image, None, request),
(GET) ["/tree/{tree}", tree: String] =>
parsebtrfs::http_tree::http_tree(&image, &tree, None, request.get_param("key").as_deref(), request).unwrap(),
btrfs_explorer::http_tree::http_tree(&image, &tree, None, request.get_param("key").as_deref(), request).unwrap(),
(GET) ["/tree/{tree}/{key}", tree: String, key: String] =>
parsebtrfs::http_tree::http_tree(&image, &tree, None, Some(&key), request).unwrap(),
btrfs_explorer::http_tree::http_tree(&image, &tree, None, Some(&key), request).unwrap(),
(GET) ["/tree/{tree}?key={key}", tree: String, key: String] =>
parsebtrfs::http_tree::http_tree(&image, &tree, None, Some(&key), request).unwrap(),
btrfs_explorer::http_tree::http_tree(&image, &tree, None, Some(&key), request).unwrap(),
(GET) ["/tree/{tree}/{method}/{key}", tree: String, method: String, key: String] =>
parsebtrfs::http_tree::http_tree(&image, &tree, Some(&method), Some(&key), request).unwrap(),
btrfs_explorer::http_tree::http_tree(&image, &tree, Some(&method), Some(&key), request).unwrap(),
(GET) ["/favicon.ico"] => Response::empty_404(),
(GET) ["/style.css"] => Response::from_file("text/css", File::open("style.css").unwrap()),
(GET) ["/htmx.min.js"] => Response::from_file("text/css", File::open("htmx.min.js").unwrap()),

View File

@ -0,0 +1,14 @@
[package]
name = "btrfs_parse_derive"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
proc-macro2 = "1.0.66"
quote = "1.0.32"
syn = "2.0.27"
[lib]
proc-macro = true

View File

@ -0,0 +1,184 @@
extern crate proc_macro;
extern crate syn;
#[macro_use]
extern crate quote;
extern crate proc_macro2;
use proc_macro2::Span;
use proc_macro::TokenStream;
use syn::{DeriveInput, Data::Enum, parse_macro_input};
#[proc_macro_derive(AllVariants)]
pub fn derive_all_variants(input: TokenStream) -> TokenStream {
let syn_item: DeriveInput = parse_macro_input!(input);
let variants = match syn_item.data {
Enum(enum_item) => {
enum_item.variants.into_iter().map(|v|v.ident)
},
_ => panic!("AllVariants only works on enums!"),
};
let enum_name = syn_item.ident;
let expanded = quote! {
impl #enum_name {
fn all_variants() -> &'static[#enum_name] {
&[ #(#enum_name::#variants),* ]
}
}
};
expanded.into()
}
#[proc_macro_derive(ParseBin, attributes(skip_bytes, len))]
pub fn derive_parse_bin(input: TokenStream) -> TokenStream {
let syn_item: DeriveInput = parse_macro_input!(input);
let name = syn_item.ident;
match syn_item.data {
syn::Data::Struct(struct_item) => {
match struct_item.fields {
syn::Fields::Named(fields_named) => {
return derive_parse_bin_struct(&name, &fields_named.named);
},
syn::Fields::Unnamed(fields_unnamed) => {
if fields_unnamed.unnamed.len() != 1 {
panic!("ParseBin does not support tuple structs!");
}
let inner_type = fields_unnamed.unnamed.into_iter().next().unwrap().ty;
return derive_parse_bin_alias(name, inner_type);
},
_ => panic!("ParseBin on unit structs makes no sense!"),
}
},
_ => panic!("ParseBin only works on structs so far!"),
};
}
fn derive_parse_bin_alias(name: syn::Ident, ty: syn::Type) -> TokenStream {
quote! {
impl ParseBin for #name {
fn parse_len(bytes: &[u8]) -> Result<(Self, usize), ParseError> {
let (result, size) = <#ty>::parse_len(bytes)?;
Ok((#name(result), size))
}
}
}.into()
}
fn derive_parse_bin_struct<'a, T>(name: &syn::Ident, fields: T) -> TokenStream
where T: IntoIterator<Item = &'a syn::Field>
{
let mut parsing_statements = Vec::new();
let mut combining_expressions = Vec::new();
for field in fields {
let field_name = field.ident.as_ref().unwrap();
let field_type = &field.ty;
let mut skip: Option<usize> = None;
let mut veclen: Option<String> = None;
// look for attributes
for at in &field.attrs {
if let syn::Meta::NameValue(nv) = &at.meta {
if nv.path.segments.len() == 1 {
let attr_name = nv.path.segments[0].ident.to_string();
if attr_name == "skip_bytes" {
if let syn::Expr::Lit(expr) = &nv.value {
if let syn::Lit::Int(nbytes) = &expr.lit {
// println!("reserved = {}", nbytes);
skip = nbytes.base10_parse::<usize>().ok()
}
}
} else if attr_name == "len" {
if let syn::Expr::Lit(expr) = &nv.value {
if let syn::Lit::Str(litstr) = &expr.lit {
// println!("len = {}", litstr.value());
veclen = Some(litstr.value());
}
}
}
}
}
}
if let Some(offset) = skip {
parsing_statements.push(quote!{
__parse_bin_derive_size += #offset;
});
}
if let Some(varname) = veclen {
let field_name_item = format_ident!("{}_item", field_name);
let field_type_item: &syn::Type = match &field_type {
syn::Type::Path(tp) => {
match tp.path.segments.iter().next() {
Some(single) => {
if &single.ident.to_string() == "Vec" {
match &single.arguments {
syn::PathArguments::AngleBracketed(args) => {
match args.args.iter().next() {
Some(firstarg) => {
match firstarg {
syn::GenericArgument::Type(ty) => {
Some(ty)
},
_ => None,
}
},
None => None,
}
},
_ => None,
}
} else {
None
}
},
None => None,
}
},
_ => None,
}.expect("The len attribute is only allowed on type Vec<_>");
let varname_ident = syn::Ident::new(&varname, Span::call_site());
parsing_statements.push(quote!{
let mut #field_name = Vec::new();
for i in 0 .. #varname_ident.0 as usize {
let #field_name_item = <#field_type_item>::parse_len(&bytes[__parse_bin_derive_size..])?;
__parse_bin_derive_size += #field_name_item.1;
#field_name.push(#field_name_item.0);
}
});
combining_expressions.push(quote!(#field_name: #field_name));
} else {
parsing_statements.push(quote!{
let #field_name = <#field_type>::parse_len(&bytes[__parse_bin_derive_size..])?;
__parse_bin_derive_size += #field_name.1;
});
combining_expressions.push(quote!(#field_name: #field_name.0));
}
}
quote! {
impl ParseBin for #name {
fn parse_len(bytes: &[u8]) -> Result<(Self, usize), ParseError> {
let mut __parse_bin_derive_size: usize = 0;
#(#parsing_statements)*
let result = #name {
#(#combining_expressions),*
};
Ok((result, __parse_bin_derive_size))
}
}
}.into()
}

View File

@ -10,9 +10,6 @@ table td {
padding: 0.1em 0.2em;
}
table tr:nth-child(even) {
}
table th {
text-align: left;
border-bottom: 1px solid #ccc;
@ -42,23 +39,10 @@ table > tbody > tr.fold.open {
display: table-row;
}
/*
table > tbody > tr.view td:first-child:before {
color: #999;
content: "x";
transition: all 0.3s ease;
}
table > tbody > tr.view.open td:first-child:before {
transform: rotate(-180deg);
color: #333;
}
*/
div.nav {
padding: 5px;
background-color: #dde;
border-radius: 5px;
border-radius: 4px;
margin: 5px 0;
overflow: hidden;
text-align: center;
@ -69,10 +53,10 @@ a.nav {
}
details.item {
padding: 5px;
padding: 3px;
background-color: #dde;
border-radius: 5px;
margin: 5px 0;
border-radius: 4px;
margin: 3px 0;
overflow: hidden;
}
@ -81,15 +65,15 @@ a {
}
details.highlight {
background-color: #abc;
background-color: #bbc;
}
details .details {
color: white;
background-color: #222;
color: black;
// background-color: #222;
padding: 10px;
margin-top: 5px;
border-radius: 5px;
border-radius: 4px;
}
details .itemvalue {
@ -103,7 +87,7 @@ details .itemvalue {
details .key {
color: white;
background-color: #999;
border-radius: 5px;
border-radius: 4px;
padding: 3px;
margin: 1px 2px;
display: inline-block;
@ -155,11 +139,11 @@ span.key_type.root {
}
.details td {
border: 1px solid white;
border: 1px solid black;
}
.details td:first-child {
border: 1px solid white;
border: 1px solid black;
width: 160px;
}