Skip to content

Commit 4c59c11

Browse files
authored
Merge pull request #1299 from spkenv/forward-to-impl-macro
Improve forward_to_impl! macro
2 parents 3b8e1b1 + 1ac123d commit 4c59c11

File tree

2 files changed

+44
-85
lines changed

2 files changed

+44
-85
lines changed

crates/spk-schema/src/package.rs

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,56 @@ use crate::{ComponentSpec, DeprecateMut, Opt, RuntimeEnvironment};
2222
mod package_test;
2323

2424
/// Macro to forward trait implementations to references, boxes, and Arcs
25+
///
26+
/// The code passed to this macro can make use of a `clone!(self)` macro that
27+
/// will clone the inner value if needed.
28+
#[macro_export]
2529
macro_rules! forward_to_impl {
26-
($trait_name:ident, { $($item:item)* }) => {
27-
impl<T: $trait_name + Send + Sync> $trait_name for std::sync::Arc<T> {
30+
(arc = true, $trait_name:ident, { $($item:item)* }) => {
31+
#[allow(unused_macros)]
32+
macro_rules! clone {
33+
($expr:expr) => {
34+
std::sync::Arc::unwrap_or_clone($expr)
35+
};
36+
}
37+
38+
impl<T: $trait_name> $trait_name for std::sync::Arc<T> {
2839
$($item)*
2940
}
41+
};
42+
(box = true, $trait_name:ident, { $($item:item)* }) => {
43+
#[allow(unused_macros)]
44+
macro_rules! clone {
45+
($expr:expr) => {
46+
(*$expr).clone()
47+
};
48+
}
3049

31-
impl<T: $trait_name + Send + Sync> $trait_name for Box<T> {
50+
impl<T: $trait_name> $trait_name for Box<T> {
3251
$($item)*
3352
}
53+
};
54+
(ref_t = true, $trait_name:ident, { $($item:item)* }) => {
55+
#[allow(unused_macros)]
56+
macro_rules! clone {
57+
($expr:expr) => {
58+
(*$expr).clone()
59+
};
60+
}
3461

35-
impl<T: $trait_name + Send + Sync> $trait_name for &T {
62+
impl<T: $trait_name> $trait_name for &T {
3663
$($item)*
3764
}
3865
};
66+
(box = false, $trait_name:ident, { $($item:item)* }) => {
67+
forward_to_impl!(arc = true, $trait_name, { $($item)* });
68+
forward_to_impl!(ref_t = true, $trait_name, { $($item)* });
69+
};
70+
($trait_name:ident, { $($item:item)* }) => {
71+
forward_to_impl!(arc = true, $trait_name, { $($item)* });
72+
forward_to_impl!(box = true, $trait_name, { $($item)* });
73+
forward_to_impl!(ref_t = true, $trait_name, { $($item)* });
74+
};
3975
}
4076

4177
/// Access to the build options defined by a package.

crates/spk-schema/src/recipe.rs

Lines changed: 4 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55
use std::borrow::Cow;
66
use std::collections::HashMap;
77
use std::path::Path;
8-
use std::sync::Arc;
98

109
use spk_schema_foundation::ident::{RequestWithOptions, VersionIdent};
1110

1211
use crate::foundation::ident_build::BuildId;
1312
use crate::foundation::option_map::OptionMap;
1413
use crate::foundation::spec_ops::{Named, Versioned};
1514
use crate::metadata::Meta;
16-
use crate::{InputVariant, Package, RequirementsList, Result, TestStage, Variant};
15+
use crate::{InputVariant, Package, RequirementsList, Result, TestStage, Variant, forward_to_impl};
1716

1817
/// Return the resolved packages from a solution.
1918
pub trait BuildEnv {
@@ -116,10 +115,7 @@ pub trait Recipe:
116115
fn validation(&self) -> &super::ValidationSpec;
117116
}
118117

119-
impl<T> Recipe for std::sync::Arc<T>
120-
where
121-
T: Recipe,
122-
{
118+
forward_to_impl!(box = false, Recipe, {
123119
type Output = T::Output;
124120
type Variant = T::Variant;
125121
type Test = T::Test;
@@ -177,7 +173,7 @@ where
177173
E: BuildEnv<Package = P>,
178174
P: Package,
179175
{
180-
Arc::unwrap_or_clone(self).generate_binary_build(variant, build_env)
176+
clone!(self).generate_binary_build(variant, build_env)
181177
}
182178

183179
fn metadata(&self) -> &Meta {
@@ -187,77 +183,4 @@ where
187183
fn validation(&self) -> &super::ValidationSpec {
188184
(**self).validation()
189185
}
190-
}
191-
192-
impl<T> Recipe for &T
193-
where
194-
T: Recipe,
195-
{
196-
type Output = T::Output;
197-
type Variant = T::Variant;
198-
type Test = T::Test;
199-
200-
fn ident(&self) -> &VersionIdent {
201-
(**self).ident()
202-
}
203-
204-
fn build_digest<V>(&self, variant: &V) -> Result<BuildId>
205-
where
206-
V: Variant,
207-
{
208-
(**self).build_digest(variant)
209-
}
210-
211-
fn build_script(&self) -> String {
212-
(**self).build_script()
213-
}
214-
215-
fn default_variants(&self, options: &OptionMap) -> Cow<'_, Vec<Self::Variant>> {
216-
(**self).default_variants(options)
217-
}
218-
219-
fn resolve_options<V>(&self, variant: &V) -> Result<OptionMap>
220-
where
221-
V: Variant,
222-
{
223-
(**self).resolve_options(variant)
224-
}
225-
226-
fn get_build_requirements<V>(
227-
&self,
228-
variant: &V,
229-
) -> Result<Cow<'_, RequirementsList<RequestWithOptions>>>
230-
where
231-
V: Variant,
232-
{
233-
(**self).get_build_requirements(variant)
234-
}
235-
236-
fn get_tests<V>(&self, stage: TestStage, variant: &V) -> Result<Vec<Self::Test>>
237-
where
238-
V: Variant,
239-
{
240-
(**self).get_tests(stage, variant)
241-
}
242-
243-
fn generate_source_build(&self, root: &Path) -> Result<Self::Output> {
244-
(**self).generate_source_build(root)
245-
}
246-
247-
fn generate_binary_build<V, E, P>(self, variant: &V, build_env: &E) -> Result<Self::Output>
248-
where
249-
V: InputVariant,
250-
E: BuildEnv<Package = P>,
251-
P: Package,
252-
{
253-
self.clone().generate_binary_build(variant, build_env)
254-
}
255-
256-
fn metadata(&self) -> &Meta {
257-
(**self).metadata()
258-
}
259-
260-
fn validation(&self) -> &super::ValidationSpec {
261-
(**self).validation()
262-
}
263-
}
186+
});

0 commit comments

Comments
 (0)