Make metadata structs more typed

This commit is contained in:
Omar Abdulla
2025-07-17 15:31:18 +03:00
parent 38e6140a7c
commit 2ef6f7ba63
5 changed files with 603 additions and 120 deletions
-97
View File
@@ -1,102 +1,5 @@
use std::{borrow::Cow, collections::HashSet, path::PathBuf};
/// Defines wrappers around types.
///
/// For example, the macro invocation seen below:
///
/// ```rust,no_run
/// define_wrapper_type!(CaseId => usize);
/// ```
///
/// Would define a wrapper type that looks like the following:
///
/// ```rust,no_run
/// pub struct CaseId(usize);
/// ```
///
/// And would also implement a number of methods on this type making it easier
/// to use.
///
/// These wrapper types become very useful as they make the code a lot easier
/// to read.
///
/// Take the following as an example:
///
/// ```rust,no_run
/// struct State {
/// contracts: HashMap<usize, HashMap<String, Vec<u8>>>
/// }
/// ```
///
/// In the above code it's hard to understand what the various types refer to or
/// what to expect them to contain.
///
/// With these wrapper types we're able to create code that's self-documenting
/// in that the types tell us what the code is referring to. The above code is
/// transformed into
///
/// ```rust,no_run
/// struct State {
/// contracts: HashMap<CaseId, HashMap<ContractName, ContractByteCode>>
/// }
/// ```
#[macro_export]
macro_rules! define_wrapper_type {
(
$(#[$meta: meta])*
$ident: ident => $ty: ty
) => {
$(#[$meta])*
pub struct $ident($ty);
impl $ident {
pub fn new(value: $ty) -> Self {
Self(value)
}
pub fn into_inner(self) -> $ty {
self.0
}
pub fn as_inner(&self) -> &$ty {
&self.0
}
}
impl AsRef<$ty> for $ident {
fn as_ref(&self) -> &$ty {
&self.0
}
}
impl AsMut<$ty> for $ident {
fn as_mut(&mut self) -> &mut $ty {
&mut self.0
}
}
impl std::ops::Deref for $ident {
type Target = $ty;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl std::ops::DerefMut for $ident {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
};
}
define_wrapper_type!(
/// Represents the ID of one of the cases in a metadata file.
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
CaseId => usize
);
/// An iterator that finds files of a certain extension in the provided directory. You can think of
/// this a glob pattern similar to: `${path}/**/*.md`
pub struct FilesWithExtensionIterator {