sketchbook 0.0.2

Interactive visual applications in Rust
Documentation
use super::mode::Mode;

/// Context for converting a value into a shape.
///
/// ```
/// # use sketchbook::aspects::draw::Context;
/// #
/// // Example of creating context.
/// let context: Context<f32, (u8, u8, u8)> = Context {
///     fill: (1, 2, 3),
///     weight: 0.4,
///     ..Context::default()
/// };
/// ```
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct Context<Num, Color> {
    /// Fill color for shape.
    pub fill: Color,

    /// Border color for shape.
    pub stroke: Color,

    /// Border width for shape.
    pub weight: Num,

    /// Mode for rectangle like shapes.
    pub rectangle_mode: Mode,

    /// Mode for ellipse like shapes.
    pub ellipse_mode: Mode,

    /// Rotation for shape.
    pub rotation: Num,
}

/// Both `ellipse_mode` and `rectangle_mode` default to `Mode::Corner`.
impl<Num, Color> Default for Context<Num, Color>
where
    Num: Default,
    Color: Default,
{
    #[inline]
    fn default() -> Self {
        Self {
            ellipse_mode: Mode::Corner,
            rectangle_mode: Mode::Corner,
            fill: Color::default(),
            stroke: Color::default(),
            weight: Num::default(),
            rotation: Num::default(),
        }
    }
}

/// Convert with extra context for the convertion.
///
/// Prefer to implement this trait instead of `IntoWithContext` because
/// `IntoWithContext` will automatically be implemented for all types
/// that implement this trait.
///
/// ```
/// # use sketchbook::aspects::draw::Context;
/// # use sketchbook::aspects::draw::Circle;
/// # use sketchbook::aspects::draw::FromWithContext;
/// let circle: Circle<f32, (u8, u8, u8)>
///     = Circle::from_with_context((2.0, 5.0, 6.5), &Context::default());
/// ```
pub trait FromWithContext<T, Num, Color> {
    /// Convert from the value in relation to a context.
    fn from_with_context(value: T, context: &Context<Num, Color>) -> Self;
}

/// Convert with extra context for the convertion.
///
/// Prefer to implement `FromWithContext` instead of this trait because
/// this trait will automatically be implemented for all types
/// that implement `FromWithContext`.
///
/// ```
/// # use sketchbook::aspects::draw::Context;
/// # use sketchbook::aspects::draw::Circle;
/// # use sketchbook::aspects::draw::IntoWithContext;
/// let circle: Circle<f32, (u8, u8, u8)>
///     = (2.0, 5.0, 6.5).into_with_context(&Context::default());
/// ```
pub trait IntoWithContext<T, Num, Color> {
    /// Convert into the value in relation to a context.
    fn into_with_context(self, context: &Context<Num, Color>) -> T;
}

/// This impl ignores the context when converting using the `From` trait.
impl<T, U, Num, Color> FromWithContext<U, Num, Color> for T
where
    T: From<U>,
{
    #[inline]
    fn from_with_context(value: U, _context: &Context<Num, Color>) -> T {
        value.into()
    }
}

impl<T, U, Num, Color> IntoWithContext<U, Num, Color> for T
where
    U: FromWithContext<T, Num, Color>,
{
    #[inline]
    fn into_with_context(self, context: &Context<Num, Color>) -> U {
        U::from_with_context(self, context)
    }
}