Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "init4-bin-base"

description = "Internal utilities for binaries produced by the init4 team"
keywords = ["init4", "bin", "base"]
version = "0.18.0-rc.7"
version = "0.18.0-rc.8"
edition = "2021"
rust-version = "1.85"
authors = ["init4", "James Prestwich", "evalir"]
Expand All @@ -12,7 +12,7 @@ homepage = "https://github.com/init4tech/bin-base"
repository = "https://github.com/init4tech/bin-base"

[dependencies]
init4-from-env-derive = "0.1.0"
init4-from-env-derive = { version = "0.2.0", path = "from-env-derive" }

# Signet
signet-constants = { version = "0.16.0-rc.7" }
Expand Down
5 changes: 2 additions & 3 deletions from-env-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "init4-from-env-derive"

description = "A derive macro for `init4_bin_base::FromEnv`"
version = "0.1.2"
version = "0.2.0"
edition = "2021"
rust-version = "1.81"
authors = ["init4", "James Prestwich"]
Expand All @@ -11,7 +11,6 @@ homepage = "https://github.com/init4tech/bin-base"
repository = "https://github.com/init4tech/bin-base"

[dependencies]
heck = "0.5.0"
proc-macro2 = "1.0.95"
quote = "1.0.40"
syn = { version = "2.0.100", features = ["full", "parsing"] }
Expand All @@ -20,4 +19,4 @@ syn = { version = "2.0.100", features = ["full", "parsing"] }
proc-macro = true

[dev-dependencies]
init4-bin-base = "0.9"
init4-bin-base = { path = ".." }
107 changes: 10 additions & 97 deletions from-env-derive/src/field.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use heck::ToPascalCase;
use proc_macro2::TokenStream;
use quote::quote;
use syn::{spanned::Spanned, Ident, LitStr};
Expand Down Expand Up @@ -89,26 +88,6 @@ impl TryFrom<&syn::Field> for Field {
}

impl Field {
pub(crate) fn trait_name(&self) -> TokenStream {
self.env_var
.as_ref()
.map(|_| quote! { FromEnvVar })
.unwrap_or(quote! { FromEnv })
}

pub(crate) fn as_trait(&self) -> TokenStream {
let field_trait = self.trait_name();
let field_type = &self.field_type;

quote! { <#field_type as #field_trait> }
}

pub(crate) fn assoc_err(&self) -> TokenStream {
let as_trait = self.as_trait();

quote! { #as_trait::Error }
}

pub(crate) fn field_name(&self, idx: usize) -> Ident {
if let Some(field_name) = self.field_name.as_ref() {
return field_name.clone();
Expand All @@ -120,41 +99,7 @@ impl Field {
.unwrap()
}

/// Produces the name of the enum variant for the field
pub(crate) fn enum_variant_name(&self, idx: usize) -> Option<TokenStream> {
if self.skip || self.infallible {
return None;
}

let n = self.field_name(idx).to_string().to_pascal_case();

let n: Ident = syn::parse_str::<Ident>(&n)
.map_err(|_| syn::Error::new(self.span, "Failed to create field name"))
.unwrap();

Some(quote! { #n })
}

/// Produces the variant, containing the error type
pub(crate) fn expand_enum_variant(&self, idx: usize) -> Option<TokenStream> {
let variant_name = self.enum_variant_name(idx)?;
let var_name_str = variant_name.to_string();
let assoc_err = self.assoc_err();

Some(quote! {
#[doc = "Error for "]
#[doc = #var_name_str]
#variant_name(#assoc_err)
})
}

/// Produces the a line for the `inventory` function
/// of the form
/// items.push(...); // (if this is a FromEnvVar)
/// or
/// items.extend(...); // (if this is a FromEnv)
/// or
/// // nothing if this is a skip
/// Produces a line for the `inventory` function
pub(crate) fn expand_env_item_info(&self) -> TokenStream {
if self.skip {
return quote! {};
Expand Down Expand Up @@ -183,39 +128,7 @@ impl Field {
}
}

pub(crate) fn expand_variant_display(&self, idx: usize) -> Option<TokenStream> {
let variant_name = self.enum_variant_name(idx)?;

Some(quote! {
Self::#variant_name(err) => err.fmt(f)
})
}

pub(crate) fn expand_variant_source(&self, idx: usize) -> Option<TokenStream> {
let variant_name = self.enum_variant_name(idx)?;

Some(quote! {
Self::#variant_name(err) => Some(err)
})
}

pub(crate) fn expand_item_from_env(&self, err_ident: &syn::Path, idx: usize) -> TokenStream {
// Produces code fo the following form:
// ```rust
// // EITHER
// let field_name = env::var(#self.env_var.unwrap()).map_err(|e| e.map(#ErroEnum::FieldName))?;

// // OR
// let field_name = FromEnvVar::from_env_var(#self.env_var.unwrap()).map_err(|e| e.map(#ErroEnum::FieldName))?;

// // OR
// let field_name = FromEnv::from_env().map_err()?;

// // OR
// let field_name = Default::default();

//```
let variant = self.enum_variant_name(idx);
pub(crate) fn expand_item_from_env(&self, idx: usize) -> TokenStream {
let field_name = self.field_name(idx);

if self.skip {
Expand All @@ -230,15 +143,15 @@ impl Field {
quote! { FromEnv::from_env() }
};

let map_line = if self.infallible {
quote! { FromEnvErr::infallible_into }
if self.infallible {
quote! {
let #field_name = #fn_invoc
.map_err(FromEnvErr::infallible_into)?;
}
} else {
quote! { |e| e.map(#err_ident::#variant) }
};

quote! {
let #field_name = #fn_invoc
.map_err(#map_line)?;
quote! {
let #field_name = #fn_invoc?;
}
}
}
}
110 changes: 2 additions & 108 deletions from-env-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,101 +102,14 @@ impl Input {
}
}

fn error_ident(&self) -> syn::Path {
if self.is_infallible() {
return syn::parse_str("::std::convert::Infallible").unwrap();
}

let error_name = format!("{}EnvError", self.ident);
syn::parse_str::<syn::Path>(&error_name)
.map_err(|_| {
syn::Error::new(self.ident.span(), "Failed to parse error ident").to_compile_error()
})
.unwrap()
}

fn is_infallible(&self) -> bool {
self.error_variants().is_empty()
}

fn error_variants(&self) -> Vec<TokenStream> {
self.fields
.iter()
.enumerate()
.flat_map(|(idx, field)| field.expand_enum_variant(idx))
.collect()
}

fn error_variant_displays(&self) -> Vec<TokenStream> {
self.fields
.iter()
.enumerate()
.flat_map(|(idx, field)| field.expand_variant_display(idx))
.collect::<Vec<_>>()
}

fn expand_variant_sources(&self) -> Vec<TokenStream> {
self.fields
.iter()
.enumerate()
.flat_map(|(idx, field)| field.expand_variant_source(idx))
.collect::<Vec<_>>()
}

fn item_from_envs(&self) -> Vec<TokenStream> {
let error_ident = self.error_ident();
self.fields
.iter()
.enumerate()
.map(|(idx, field)| field.expand_item_from_env(&error_ident, idx))
.map(|(idx, field)| field.expand_item_from_env(idx))
.collect()
}

fn expand_error(&self) -> TokenStream {
let error_ident = self.error_ident();
let struct_name_str = &self.ident.to_string();

let error_variants = self.error_variants();
let error_variant_displays = self.error_variant_displays();
let error_variant_sources = self.expand_variant_sources();

if error_variants.is_empty() {
return Default::default();
}

quote! {
#[doc = "Generated error type for [`FromEnv`] for"]
#[doc = #struct_name_str]
#[doc = ". This error type is used to represent errors that occur when trying to create an instance of the struct from environment variables."]
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum #error_ident {
#(#error_variants),*
}

#[automatically_derived]
impl ::core::fmt::Display for #error_ident {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
match self {
#(
#error_variant_displays,
)*
}
}
}

#[automatically_derived]
impl ::core::error::Error for #error_ident {
fn source(&self) -> Option<&(dyn ::core::error::Error + 'static)> {
match self {
#(
#error_variant_sources,
)*
}
}
}
}
}

fn env_item_info(&self) -> Vec<TokenStream> {
self.fields
.iter()
Expand All @@ -208,16 +121,12 @@ impl Input {
let env_item_info = self.env_item_info();
let struct_name = &self.ident;

let error_ident = self.error_ident();

let item_from_envs = self.item_from_envs();
let struct_instantiation = self.instantiate_struct();

quote! {
#[automatically_derived]
impl FromEnv for #struct_name {
type Error = #error_ident;

fn inventory() -> ::std::vec::Vec<&'static EnvItemInfo> {
let mut items = ::std::vec::Vec::new();
#(
Expand All @@ -226,7 +135,7 @@ impl Input {
items
}

fn from_env() -> ::std::result::Result<Self, FromEnvErr<Self::Error>> {
fn from_env() -> ::std::result::Result<Self, FromEnvErr> {
#(
#item_from_envs
)*
Expand All @@ -238,33 +147,18 @@ impl Input {
}

fn expand_mod(&self) -> TokenStream {
// let expanded_impl = expand_impl(input);
let expanded_impl = self.expand_impl();
let crate_name = &self.crate_name;

let mod_ident =
syn::parse_str::<syn::Ident>(&format!("__from_env_impls_{}", self.ident)).unwrap();

let expanded_error = self.expand_error();

let use_err = if !expanded_error.is_empty() {
let error_ident = self.error_ident();
quote! {
pub use #mod_ident::#error_ident;
}
} else {
quote! {}
};

quote! {
#use_err
mod #mod_ident {
use super::*;
use #crate_name::utils::from_env::{FromEnv, FromEnvErr, FromEnvVar, EnvItemInfo};

#expanded_impl

#expanded_error
}
}
}
Expand Down
4 changes: 1 addition & 3 deletions src/perms/builders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,7 @@ impl Builder {
}

impl FromEnvVar for Builder {
type Error = std::convert::Infallible;

fn from_env_var(env_var: &str) -> Result<Self, FromEnvErr<Self::Error>> {
fn from_env_var(env_var: &str) -> Result<Self, FromEnvErr> {
Ok(Self {
sub: String::from_env_var(env_var)?,
})
Expand Down
4 changes: 2 additions & 2 deletions src/perms/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
pub(crate) mod builders;
pub use builders::{Builder, BuilderPermissionError, Builders, BuildersEnvError};
pub use builders::{Builder, BuilderPermissionError, Builders};

pub(crate) mod config;
pub use config::{SlotAuthzConfig, SlotAuthzConfigEnvError};
pub use config::SlotAuthzConfig;

pub(crate) mod oauth;
pub use oauth::{Authenticator, OAuthConfig, SharedToken};
Expand Down
6 changes: 2 additions & 4 deletions src/utils/calc.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::utils::from_env::{EnvItemInfo, FromEnv, FromEnvErr, FromEnvVar};
#[allow(deprecated)]
use signet_constants::{mainnet, parmigiana, pecorino, test_utils, KnownChains};
use std::{num::ParseIntError, str::FromStr};
use std::str::FromStr;

/// A slot calculator, which can calculate slot numbers, windows, and offsets
/// for a given chain.
Expand Down Expand Up @@ -293,8 +293,6 @@ impl SlotCalculator {
}

impl FromEnv for SlotCalculator {
type Error = ParseIntError;

fn inventory() -> Vec<&'static EnvItemInfo> {
vec![
&EnvItemInfo {
Expand All @@ -320,7 +318,7 @@ impl FromEnv for SlotCalculator {
]
}

fn from_env() -> Result<Self, FromEnvErr<Self::Error>> {
fn from_env() -> Result<Self, FromEnvErr> {
if let Ok(slot_calculator) = SlotCalculator::from_env_var("CHAIN_NAME") {
return Ok(slot_calculator);
}
Expand Down
Loading