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 crates/cgp-macro-lib/src/cgp_impl/use_provider.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use syn::parse::{Parse, ParseStream};
use syn::punctuated::Punctuated;
use syn::token::{Colon, Comma};
use syn::token::{Colon, Plus};
use syn::{Type, parse_quote};

use crate::parse::SimpleType;

pub struct UseProviderSpec {
pub context_type: Type,
pub provider_type: Type,
pub provider_trait_bounds: Punctuated<SimpleType, Comma>,
pub provider_trait_bounds: Punctuated<SimpleType, Plus>,
}

impl Parse for UseProviderSpec {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use core::ops::Mul;

use cgp::prelude::*;

#[cgp_component(AreaCalculator)]
pub trait CanCalculateArea {
fn area(&self) -> f64;
}

#[cgp_impl(new RectangleArea)]
impl<Scalar> AreaCalculator
where
Scalar: Mul<Output = Scalar> + Clone + Into<f64>,
{
fn area(&self, #[implicit] width: Scalar, #[implicit] height: Scalar) -> f64 {
(width * height).into()
}
}

#[derive(HasField)]
pub struct Rectangle {
pub width: f64,
pub height: f64,
}

delegate_and_check_components! {
CanUseRectangle for Rectangle;
Rectangle {
AreaCalculatorComponent:
RectangleArea,
}
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod basic;
pub mod generics;
pub mod import;
1 change: 1 addition & 0 deletions crates/cgp-tests/tests/component_tests/cgp_impl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ pub mod basic;
pub mod impl_self;
pub mod implicit_args;
pub mod implicit_context;
pub mod shape;
pub mod use_provider;
176 changes: 176 additions & 0 deletions crates/cgp-tests/tests/component_tests/cgp_impl/shape.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
use core::f64::consts::PI;

use cgp::prelude::*;

#[cgp_fn]
pub fn rectangle_area(&self, #[implicit] width: f64, #[implicit] height: f64) -> f64 {
width * height
}

#[cgp_fn]
pub fn circle_area(&self, #[implicit] radius: f64) -> f64 {
PI * radius * radius
}

#[cgp_component(AreaCalculator)]
pub trait CanCalculateArea {
fn area(&self) -> f64;
}

#[cgp_impl(new RectangleAreaCalculator)]
impl AreaCalculator {
fn area(&self, #[implicit] width: f64, #[implicit] height: f64) -> f64 {
width * height
}
}

#[cgp_impl(new CircleAreaCalculator)]
impl AreaCalculator {
fn area(&self, #[implicit] radius: f64) -> f64 {
PI * radius * radius
}
}

#[cgp_impl(new ScaledRectangleAreaCalculator)]
#[use_provider(RectangleAreaCalculator: AreaCalculator)]
impl AreaCalculator {
fn area(&self, #[implicit] scale_factor: f64) -> f64 {
RectangleAreaCalculator::area(self) * scale_factor * scale_factor
}
}

#[cgp_impl(new ScaledCircleAreaCalculator)]
#[use_provider(CircleAreaCalculator: AreaCalculator)]
impl AreaCalculator {
fn area(&self, #[implicit] scale_factor: f64) -> f64 {
CircleAreaCalculator::area(self) * scale_factor * scale_factor
}
}

#[cgp_impl(new ScaledAreaCalculator<InnerCalculator>)]
#[use_provider(InnerCalculator: AreaCalculator)]
impl<InnerCalculator> AreaCalculator {
fn area(&self, #[implicit] scale_factor: f64) -> f64 {
let base_area = InnerCalculator::area(self);

base_area * scale_factor * scale_factor
}
}

#[derive(HasField)]
pub struct IsThisRectangleOrCircle {
pub width: f64,
pub height: f64,
pub radius: f64,
}

impl CanCalculateArea for IsThisRectangleOrCircle {
fn area(&self) -> f64 {
CircleAreaCalculator::area(self)
}
}

#[test]
fn test_rectangle_or_circle() {
let rectangle_or_circle = IsThisRectangleOrCircle {
width: 2.0,
height: 3.0,
radius: 4.0,
};

let area = rectangle_or_circle.area();
assert_eq!(area, 16.0 * PI);

let rectangle_area = RectangleAreaCalculator::area(&rectangle_or_circle);
assert_eq!(rectangle_area, 6.0);

let circle_area = CircleAreaCalculator::area(&rectangle_or_circle);
assert_eq!(circle_area, 16.0 * PI);

let rectangle_area = rectangle_or_circle.rectangle_area();
assert_eq!(rectangle_area, 6.0);

let circle_area = rectangle_or_circle.circle_area();
assert_eq!(circle_area, 16.0 * PI);
}

#[derive(HasField)]
pub struct PlainRectangle {
pub width: f64,
pub height: f64,
}

delegate_components! {
PlainRectangle {
AreaCalculatorComponent:
RectangleAreaCalculator,
}
}

#[derive(HasField)]
pub struct ScaledRectangle {
pub scale_factor: f64,
pub width: f64,
pub height: f64,
}

delegate_components! {
ScaledRectangle {
AreaCalculatorComponent:
ScaledAreaCalculator<RectangleAreaCalculator>,
}
}

#[derive(HasField)]
pub struct PlainCircle {
pub radius: f64,
}

delegate_components! {
PlainCircle {
AreaCalculatorComponent:
CircleAreaCalculator,
}
}

#[derive(HasField)]
pub struct ScaledCircle {
pub scale_factor: f64,
pub radius: f64,
}

delegate_components! {
ScaledCircle {
AreaCalculatorComponent:
ScaledAreaCalculator<CircleAreaCalculator>,
}
}

#[test]
fn test_scaled_area() {
let rectangle = PlainRectangle {
width: 3.0,
height: 4.0,
};

assert_eq!(rectangle.area(), 12.0);

let scaled_rectangle = ScaledRectangle {
scale_factor: 2.0,
width: 3.0,
height: 4.0,
};

let circle = PlainCircle { radius: 3.0 };

assert_eq!(circle.area(), 9.0 * PI);

assert_eq!(scaled_rectangle.area(), 48.0);

let scaled_circle = ScaledCircle {
scale_factor: 2.0,
radius: 3.0,
};

assert_eq!(scaled_circle.area(), 36.0 * PI);
}
12 changes: 12 additions & 0 deletions crates/cgp-tests/tests/component_tests/cgp_impl/use_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,15 @@ impl<Inner> AreaCalculator {
base_area * scale_factor * scale_factor
}
}

#[derive(HasField)]
pub struct Rectangle {
pub width: f64,
pub height: f64,
}

impl CanCalculateArea for Rectangle {
fn area(&self) -> f64 {
RectangleArea::area(self)
}
}
Loading