mirror of
https://github.com/ricoriedel/wipe.git
synced 2024-11-26 01:46:36 +00:00
Add sampler
This commit is contained in:
parent
56e630204a
commit
8d75146744
35
Cargo.lock
generated
35
Cargo.lock
generated
@ -38,6 +38,12 @@ version = "1.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "convert_case"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossterm"
|
name = "crossterm"
|
||||||
version = "0.24.0"
|
version = "0.24.0"
|
||||||
@ -63,6 +69,19 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_more"
|
||||||
|
version = "0.99.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
|
||||||
|
dependencies = [
|
||||||
|
"convert_case",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"rustc_version",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "difflib"
|
name = "difflib"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@ -293,12 +312,27 @@ version = "0.6.27"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
|
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||||
|
dependencies = [
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "1.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal-hook"
|
name = "signal-hook"
|
||||||
version = "0.3.14"
|
version = "0.3.14"
|
||||||
@ -435,5 +469,6 @@ version = "2.0.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"approx",
|
"approx",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
|
"derive_more",
|
||||||
"mockall",
|
"mockall",
|
||||||
]
|
]
|
||||||
|
@ -8,6 +8,7 @@ authors = ["Rico Riedel"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
crossterm = "0.24"
|
crossterm = "0.24"
|
||||||
|
derive_more = "0.99"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
mockall = "0.11"
|
mockall = "0.11"
|
||||||
|
@ -1,27 +1,40 @@
|
|||||||
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||||
|
pub enum CharSample {
|
||||||
|
Keep,
|
||||||
|
Draw(char),
|
||||||
|
Clear,
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(test, mockall::automock)]
|
#[cfg_attr(test, mockall::automock)]
|
||||||
pub trait CharConverter {
|
pub trait CharConverter {
|
||||||
fn convert(&self, level: f32) -> char;
|
fn convert(&self, level: f32) -> CharSample;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CharConverterImpl {
|
pub struct CharConverterImpl {
|
||||||
chars: String,
|
chars: String,
|
||||||
count: usize,
|
count: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CharConverterImpl {
|
impl CharConverterImpl {
|
||||||
pub fn new(chars: String) -> Self {
|
pub fn new(chars: String) -> Self {
|
||||||
let count = chars.chars().count();
|
let count = chars.chars().count() as f32;
|
||||||
|
|
||||||
Self { chars, count }
|
Self { chars, count }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CharConverter for CharConverterImpl {
|
impl CharConverter for CharConverterImpl {
|
||||||
fn convert(&self, level: f32) -> char {
|
fn convert(&self, level: f32) -> CharSample {
|
||||||
let len = self.count as f32;
|
if level < 0.0 {
|
||||||
let index = (level * len).rem_euclid(len) as usize;
|
CharSample::Keep
|
||||||
|
} else if level < 1.0 {
|
||||||
|
let index = (level * self.count) as usize;
|
||||||
|
let char = self.chars.chars().nth(index).unwrap();
|
||||||
|
|
||||||
self.chars.chars().nth(index).unwrap()
|
CharSample::Draw(char)
|
||||||
|
} else {
|
||||||
|
CharSample::Clear
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,37 +43,26 @@ mod test {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn convert_negative_index() {
|
fn convert_keep() {
|
||||||
let converter = CharConverterImpl::new("abc".to_string());
|
let converter = CharConverterImpl::new("abc".to_string());
|
||||||
|
|
||||||
assert_eq!('c', converter.convert(-0.2));
|
assert_eq!(CharSample::Keep, converter.convert(-0.1));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn convert_index_zero() {
|
fn convert_draw() {
|
||||||
let converter = CharConverterImpl::new("abc".to_string());
|
let converter = CharConverterImpl::new("xyz".to_string());
|
||||||
|
|
||||||
assert_eq!('a', converter.convert(0.0));
|
assert_eq!(CharSample::Draw('x'), converter.convert(0.0));
|
||||||
|
assert_eq!(CharSample::Draw('y'), converter.convert(0.5));
|
||||||
|
assert_eq!(CharSample::Draw('z'), converter.convert(0.9));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn convert() {
|
fn convert_clear() {
|
||||||
let converter = CharConverterImpl::new("abc".to_string());
|
let converter = CharConverterImpl::new("123".to_string());
|
||||||
|
|
||||||
assert_eq!('b', converter.convert(0.5));
|
assert_eq!(CharSample::Clear, converter.convert(1.0));
|
||||||
}
|
assert_eq!(CharSample::Clear, converter.convert(1.5));
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn convert_index_one() {
|
|
||||||
let converter = CharConverterImpl::new("abc".to_string());
|
|
||||||
|
|
||||||
assert_eq!('a', converter.convert(1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn convert_index_above_one() {
|
|
||||||
let converter = CharConverterImpl::new("abc".to_string());
|
|
||||||
|
|
||||||
assert_eq!('b', converter.convert(1.5));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
|
||||||
pub enum Level {
|
|
||||||
Keep,
|
|
||||||
Draw(f32),
|
|
||||||
Clear,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(test, mockall::automock)]
|
|
||||||
pub trait LevelConverter {
|
|
||||||
fn convert(&self, level: f32) -> Level;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct LevelConverterImpl;
|
|
||||||
|
|
||||||
impl LevelConverter for LevelConverterImpl {
|
|
||||||
fn convert(&self, level: f32) -> Level {
|
|
||||||
if level < 0.0 {
|
|
||||||
Level::Keep
|
|
||||||
} else if level < 1.0 {
|
|
||||||
Level::Draw(level)
|
|
||||||
} else {
|
|
||||||
Level::Clear
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn convert_keep() {
|
|
||||||
let converter = LevelConverterImpl::default();
|
|
||||||
|
|
||||||
assert_eq!(Level::Keep, converter.convert(-0.1));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn convert_draw() {
|
|
||||||
let converter = LevelConverterImpl::default();
|
|
||||||
|
|
||||||
assert_eq!(Level::Draw(0.0), converter.convert(0.0));
|
|
||||||
assert_eq!(Level::Draw(0.5), converter.convert(0.5));
|
|
||||||
assert_eq!(Level::Draw(0.9), converter.convert(0.9));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn convert_clear() {
|
|
||||||
let converter = LevelConverterImpl::default();
|
|
||||||
|
|
||||||
assert_eq!(Level::Clear, converter.convert(1.0));
|
|
||||||
assert_eq!(Level::Clear, converter.convert(1.5));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,44 +1,30 @@
|
|||||||
use crate::convert::char::CharConverter;
|
use crate::convert::char::{CharConverter, CharSample};
|
||||||
use crate::convert::color::ColorConverter;
|
use crate::convert::color::ColorConverter;
|
||||||
use crate::convert::level::{Level, LevelConverter};
|
|
||||||
use crossterm::style::Color;
|
use crossterm::style::Color;
|
||||||
|
|
||||||
mod char;
|
pub mod char;
|
||||||
mod color;
|
pub mod color;
|
||||||
mod level;
|
|
||||||
|
|
||||||
|
#[cfg_attr(test, mockall::automock)]
|
||||||
pub trait Converter {
|
pub trait Converter {
|
||||||
fn char(&self, level: f32) -> char;
|
fn char(&self, level: f32) -> CharSample;
|
||||||
fn color(&self, level: f32) -> Color;
|
fn color(&self, level: f32) -> Color;
|
||||||
fn level(&self, level: f32) -> Level;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ConverterImpl<T1, T2, T3> {
|
#[derive(derive_more::Constructor)]
|
||||||
|
pub struct ConverterImpl<T1, T2> {
|
||||||
char: T1,
|
char: T1,
|
||||||
color: T2,
|
color: T2,
|
||||||
level: T3,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T1, T2, T3> ConverterImpl<T1, T2, T3> {
|
impl<T1: CharConverter, T2: ColorConverter> Converter for ConverterImpl<T1, T2> {
|
||||||
pub fn new(char: T1, color: T2, level: T3) -> Self {
|
fn char(&self, level: f32) -> CharSample {
|
||||||
Self { char, color, level }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T1: CharConverter, T2: ColorConverter, T3: LevelConverter> Converter
|
|
||||||
for ConverterImpl<T1, T2, T3>
|
|
||||||
{
|
|
||||||
fn char(&self, level: f32) -> char {
|
|
||||||
self.char.convert(level)
|
self.char.convert(level)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn color(&self, level: f32) -> Color {
|
fn color(&self, level: f32) -> Color {
|
||||||
self.color.convert(level)
|
self.color.convert(level)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn level(&self, level: f32) -> Level {
|
|
||||||
self.level.convert(level)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -46,51 +32,34 @@ mod test {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::convert::char::MockCharConverter;
|
use crate::convert::char::MockCharConverter;
|
||||||
use crate::convert::color::MockColorConverter;
|
use crate::convert::color::MockColorConverter;
|
||||||
use crate::convert::level::MockLevelConverter;
|
use mockall::predicate::*;
|
||||||
use mockall::predicate::eq;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn char() {
|
fn char() {
|
||||||
let mut char = MockCharConverter::new();
|
let mut char = MockCharConverter::new();
|
||||||
let color = MockColorConverter::new();
|
let color = MockColorConverter::new();
|
||||||
let level = MockLevelConverter::new();
|
|
||||||
|
|
||||||
char.expect_convert().with(eq(4.0)).return_const('M');
|
char.expect_convert()
|
||||||
|
.with(eq(4.0))
|
||||||
|
.return_const(CharSample::Draw('M'));
|
||||||
|
|
||||||
let converter = ConverterImpl::new(char, color, level);
|
let converter = ConverterImpl::new(char, color);
|
||||||
|
|
||||||
assert_eq!('M', converter.char(4.0));
|
assert_eq!(CharSample::Draw('M'), converter.char(4.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn color() {
|
fn color() {
|
||||||
let char = MockCharConverter::new();
|
let char = MockCharConverter::new();
|
||||||
let mut color = MockColorConverter::new();
|
let mut color = MockColorConverter::new();
|
||||||
let level = MockLevelConverter::new();
|
|
||||||
|
|
||||||
color
|
color
|
||||||
.expect_convert()
|
.expect_convert()
|
||||||
.with(eq(2.0))
|
.with(eq(2.0))
|
||||||
.return_const(Color::Yellow);
|
.return_const(Color::Yellow);
|
||||||
|
|
||||||
let converter = ConverterImpl::new(char, color, level);
|
let converter = ConverterImpl::new(char, color);
|
||||||
|
|
||||||
assert_eq!(Color::Yellow, converter.color(2.0));
|
assert_eq!(Color::Yellow, converter.color(2.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn level() {
|
|
||||||
let char = MockCharConverter::new();
|
|
||||||
let color = MockColorConverter::new();
|
|
||||||
let mut level = MockLevelConverter::new();
|
|
||||||
|
|
||||||
level
|
|
||||||
.expect_convert()
|
|
||||||
.with(eq(3.0))
|
|
||||||
.return_const(Level::Draw(2.0));
|
|
||||||
|
|
||||||
let converter = ConverterImpl::new(char, color, level);
|
|
||||||
|
|
||||||
assert_eq!(Level::Draw(2.0), converter.level(3.0));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ pub mod printer;
|
|||||||
pub mod convert;
|
pub mod convert;
|
||||||
pub mod term;
|
pub mod term;
|
||||||
mod vec;
|
mod vec;
|
||||||
|
mod sampler;
|
||||||
|
|
||||||
fn main() -> Result<(), error::Error> {
|
fn main() -> Result<(), error::Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -17,6 +17,7 @@ pub trait PatternFactory {
|
|||||||
fn create(&self, config: &Config) -> Box<dyn Pattern>;
|
fn create(&self, config: &Config) -> Box<dyn Pattern>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(test, mockall::automock)]
|
||||||
pub trait Pattern {
|
pub trait Pattern {
|
||||||
fn sample(&self, pos: Vector) -> f32;
|
fn sample(&self, pos: Vector) -> f32;
|
||||||
}
|
}
|
||||||
|
142
src/sampler.rs
Normal file
142
src/sampler.rs
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
use crate::convert::char::CharSample;
|
||||||
|
use crate::convert::Converter;
|
||||||
|
use crate::pattern::{Config, Pattern, PatternFactory};
|
||||||
|
use crate::vec::Vector;
|
||||||
|
use crossterm::style::Color;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||||
|
pub enum Sample {
|
||||||
|
Keep,
|
||||||
|
Draw { char: char, color: Color },
|
||||||
|
Clear,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait SamplerFactory {
|
||||||
|
fn create(&self, config: &Config) -> Box<dyn Sampler>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Sampler {
|
||||||
|
fn sample(&self, pos: Vector) -> Sample;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(derive_more::Constructor)]
|
||||||
|
pub struct SamplerFactoryImpl<T> {
|
||||||
|
char: Box<dyn PatternFactory>,
|
||||||
|
color: Box<dyn PatternFactory>,
|
||||||
|
converter: Rc<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(derive_more::Constructor)]
|
||||||
|
pub struct SamplerImpl<T> {
|
||||||
|
char: Box<dyn Pattern>,
|
||||||
|
color: Box<dyn Pattern>,
|
||||||
|
converter: Rc<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Converter + 'static> SamplerFactory for SamplerFactoryImpl<T> {
|
||||||
|
fn create(&self, config: &Config) -> Box<dyn Sampler> {
|
||||||
|
Box::new(SamplerImpl::new(
|
||||||
|
self.char.create(config),
|
||||||
|
self.color.create(config),
|
||||||
|
self.converter.clone(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Converter> Sampler for SamplerImpl<T> {
|
||||||
|
fn sample(&self, pos: Vector) -> Sample {
|
||||||
|
match self.converter.char(self.char.sample(pos)) {
|
||||||
|
CharSample::Keep => Sample::Keep,
|
||||||
|
CharSample::Draw(char) => Sample::Draw {
|
||||||
|
char,
|
||||||
|
color: self.converter.color(self.color.sample(pos)),
|
||||||
|
},
|
||||||
|
CharSample::Clear => Sample::Clear,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
use crate::convert::MockConverter;
|
||||||
|
use crate::pattern::MockPattern;
|
||||||
|
use mockall::predicate::eq;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sample_keep() {
|
||||||
|
let color = MockPattern::new();
|
||||||
|
let mut char = MockPattern::new();
|
||||||
|
let mut converter = MockConverter::new();
|
||||||
|
|
||||||
|
char.expect_sample().return_const(3.0);
|
||||||
|
converter.expect_char().return_const(CharSample::Keep);
|
||||||
|
|
||||||
|
let sampler = SamplerImpl::new(Box::new(char), Box::new(color), Rc::new(converter));
|
||||||
|
|
||||||
|
assert_eq!(Sample::Keep, sampler.sample(Vector::default()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sample_draw() {
|
||||||
|
let mut char = MockPattern::new();
|
||||||
|
let mut color = MockPattern::new();
|
||||||
|
let mut converter = MockConverter::new();
|
||||||
|
|
||||||
|
char.expect_sample().return_const(3.0);
|
||||||
|
color.expect_sample().return_const(2.0);
|
||||||
|
converter.expect_char().return_const(CharSample::Draw('M'));
|
||||||
|
converter.expect_color().return_const(Color::Red);
|
||||||
|
|
||||||
|
let sampler = SamplerImpl::new(Box::new(char), Box::new(color), Rc::new(converter));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Sample::Draw {
|
||||||
|
char: 'M',
|
||||||
|
color: Color::Red
|
||||||
|
},
|
||||||
|
sampler.sample(Vector::default())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sample_clear() {
|
||||||
|
let color = MockPattern::new();
|
||||||
|
let mut char = MockPattern::new();
|
||||||
|
let mut converter = MockConverter::new();
|
||||||
|
|
||||||
|
char.expect_sample().return_const(3.0);
|
||||||
|
converter.expect_char().return_const(CharSample::Clear);
|
||||||
|
|
||||||
|
let sampler = SamplerImpl::new(Box::new(char), Box::new(color), Rc::new(converter));
|
||||||
|
|
||||||
|
assert_eq!(Sample::Clear, sampler.sample(Vector::default()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sample_args_correct() {
|
||||||
|
let mut char = MockPattern::new();
|
||||||
|
let mut color = MockPattern::new();
|
||||||
|
let mut converter = MockConverter::new();
|
||||||
|
|
||||||
|
char.expect_sample()
|
||||||
|
.with(eq(Vector::new(4.0, 2.0)))
|
||||||
|
.return_const(6.0);
|
||||||
|
color
|
||||||
|
.expect_sample()
|
||||||
|
.with(eq(Vector::new(4.0, 2.0)))
|
||||||
|
.return_const(7.0);
|
||||||
|
converter
|
||||||
|
.expect_char()
|
||||||
|
.with(eq(6.0))
|
||||||
|
.return_const(CharSample::Draw('A'));
|
||||||
|
converter
|
||||||
|
.expect_color()
|
||||||
|
.with(eq(7.0))
|
||||||
|
.return_const(Color::Reset);
|
||||||
|
|
||||||
|
SamplerImpl::new(Box::new(char), Box::new(color), Rc::new(converter))
|
||||||
|
.sample(Vector::new(4.0, 2.0));
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
use std::ops::Sub;
|
use std::ops::Sub;
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
#[derive(Copy, Clone, PartialEq, Debug, Default)]
|
||||||
pub struct Vector {
|
pub struct Vector {
|
||||||
pub x: f32,
|
pub x: f32,
|
||||||
pub y: f32,
|
pub y: f32,
|
||||||
|
Loading…
Reference in New Issue
Block a user