WIP: image processing library (or libraries?) #12

Draft
schrottkatze wants to merge 15 commits from schrottkatze/iowo:proc-libs into main
6 changed files with 19 additions and 69 deletions
Showing only changes of commit a3e357a0e7 - Show all commits

View file

@ -87,7 +87,8 @@ mod dev {
let pipe = PipelineBuilder::new().add(1).stringify().build(); let pipe = PipelineBuilder::new().add(1).stringify().build();
println!( println!(
multisamplednight marked this conversation as resolved Outdated

All of these dev commands seem like they'd belong into tests using #[test] instead.

All of these dev commands seem like they'd belong into tests using `#[test]` instead.

that's what i already mentioned, that i prefer playing around like that

sure, can do that, but i much prefer having them run like that and output there so i can see it more or less interactively.

planning to do that, but the experimental things are all termporary anyway.

that's what i already mentioned, that i prefer playing around like that sure, can do that, but i much prefer having them run like that and output there so i can see it more or less interactively. planning to do that, but the `experimental` things are all termporary anyway.

sure, can do that, but i much prefer having them run like that and output there so i can see it more or less interactively.

They're still just as interactive if one were to use cargo test --no-capture <test_name>.

planning to do that, but the experimental things are all termporary [sic] anyway.

They're what this PR introduces and what you requested my review on.

> sure, can do that, but i much prefer having them run like that and output there so i can see it more or less interactively. They're still just as interactive if one were to use `cargo test --no-capture <test_name>`. > planning to do that, but the `experimental` things are all termporary [sic] anyway. They're what this PR introduces and what you requested my review on.

They are indeed not what this PR introduces, those will not be in the PR once it's complete. this is basically just a working copy/scratchpad state for now, and i'll be purging it once the actual library is done which is then what will be introduced by this PR.

They are indeed not what this PR introduces, those will not be in the PR once it's complete. this is basically just a working copy/scratchpad state for now, and i'll be purging it once the actual library is done which is then what will be introduced by this PR.

Fair enough.

Fair enough.
"{:?}", "{:?}",
pipe.run(vec![num0.into(), num1.into()].into()).into_inner()[0] pipe.run(vec![&num0.into(), &num1.into()].into())
.into_inner()[0]
); );
} }
} }

View file

@ -37,7 +37,7 @@ impl Available {
#[must_use] #[must_use]
pub fn pick(&self) -> Box<dyn Evaluator> { pub fn pick(&self) -> Box<dyn Evaluator> {
match self { match self {
Self::Debug => Box::new(kind::debug::Evaluator::default()), Self::Debug => Box::<kind::debug::Evaluator>::default(),
} }
} }
} }

View file

@ -1,26 +1,19 @@
//! Types for element and pipeline IO //! Types for element and pipeline IO
use std::convert::Into; use std::{borrow::ToOwned, convert::Into};
use super::raw::{Data, DataRef}; use super::raw::Data;
/// Newtype struct with borrowed types for pipeline/element inputs, so that doesn't force a move or clone /// Newtype struct with borrowed types for pipeline/element inputs, so that doesn't force a move or clone
schrottkatze marked this conversation as resolved

Quite ambiguous doc-comment also regarding the rather lengthy doc-comment on the type itself.
How about removing this method altogether and making the content of Inputs directly public,
given that one's free to convert from/to it already?

Quite ambiguous doc-comment also regarding the rather lengthy doc-comment on the type itself. How about removing this method altogether and making the content of `Inputs` directly public, given that one's free to convert from/to it already?
pub struct Inputs<'a>(Vec<DataRef<'a>>); pub struct Inputs<'a>(pub Vec<&'a Data>);
impl<'a> Inputs<'a> { impl<'a> From<Vec<&'a Data>> for Inputs<'a> {
/// get inner value(s) fn from(value: Vec<&'a Data>) -> Self {
pub(crate) fn inner(&self) -> Vec<DataRef<'a>> {
self.0.clone()
}
}
impl<'a> From<Vec<DataRef<'a>>> for Inputs<'a> {
fn from(value: Vec<DataRef<'a>>) -> Self {
Self(value) Self(value)
} }
} }
impl<'a, T: Into<DataRef<'a>>> From<T> for Inputs<'a> { impl<'a, T: Into<&'a Data>> From<T> for Inputs<'a> {
fn from(value: T) -> Self { fn from(value: T) -> Self {
Self(vec![value.into()]) Self(vec![value.into()])
} }
@ -53,12 +46,6 @@ impl<T: Into<Data>> From<T> for Outputs {
} }
impl From<Inputs<'_>> for Outputs { impl From<Inputs<'_>> for Outputs {
fn from(value: Inputs) -> Self { fn from(value: Inputs) -> Self {
Self( Self(value.0.into_iter().map(ToOwned::to_owned).collect())
value
.0
.into_iter()
.map(|i: DataRef<'_>| DataRef::to_owned_data(&i))
.collect(),
)
} }
} }

View file

@ -1,6 +1,6 @@
//! Dynamic data storage and transfer types for use in [`io`] //! Dynamic data storage and transfer types for use in [`io`]
/// Owned data type, for use mostly in outputs and storage // Dynamic data type
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Data { pub enum Data {
schrottkatze marked this conversation as resolved Outdated

Given the common pattern of AsRef in the stdlib and InstructionRef already being used in this project, how about renaming OwnedData → Data and Data below → DataRef?

Given the common pattern of `AsRef` in the stdlib and `InstructionRef` already being used in this project, how about renaming `OwnedData` → `Data` and `Data` below → `DataRef`?

did the renaming, gonna take care of the AsRef impl later (I remember trying that earlier and something causing problems, i forgot what that was though.)

did the renaming, gonna take care of the `AsRef` impl later (I remember trying that earlier and something causing problems, i forgot what that was though.)
String(String), String(String),
@ -18,41 +18,3 @@ impl From<i32> for Data {
Self::Int(value) Self::Int(value)
} }
} }
/// Unowned data type, for inputs into runner functions
#[derive(Clone, Copy, Debug)]
pub enum DataRef<'a> {
String(&'a str),
Int(i32),
}
impl DataRef<'_> {
/// converts itself to `OwnedData`
pub fn to_owned_data(&self) -> Data {
match self {
DataRef::String(s) => (*s).to_owned().into(),
DataRef::Int(i) => (*i).into(),
}
}
}
impl<'a> From<&'a str> for DataRef<'a> {
fn from(value: &'a str) -> Self {
Self::String(value)
}
}
impl From<i32> for DataRef<'_> {
fn from(value: i32) -> Self {
Self::Int(value)
}
}
impl<'a> From<&'a Data> for DataRef<'a> {
fn from(value: &'a Data) -> Self {
match value {
Data::String(s) => DataRef::String(s),
Data::Int(i) => DataRef::Int(*i),
}
}
}

View file

@ -4,7 +4,7 @@ use core::panic;
use crate::experimental::trait_based::{ use crate::experimental::trait_based::{
data::{ data::{
io::{Inputs, Outputs}, io::{Inputs, Outputs},
raw::DataRef, raw::Data,
}, },
element::{DataType, ElementSignature, PipelineElement}, element::{DataType, ElementSignature, PipelineElement},
}; };
@ -14,7 +14,7 @@ pub struct Add(pub i32);
impl PipelineElement for Add { impl PipelineElement for Add {
fn runner(&self) -> fn(&Inputs) -> Outputs { fn runner(&self) -> fn(&Inputs) -> Outputs {
|input| { |input| {
let [DataRef::Int(i0), DataRef::Int(i1), ..] = input.inner()[..] else { let [Data::Int(i0), Data::Int(i1), ..] = input.0[..] else {
panic!("Invalid data passed") panic!("Invalid data passed")
}; };
(i0 + i1).into() (i0 + i1).into()
@ -34,7 +34,7 @@ pub struct Subtract(pub i32);
impl PipelineElement for Subtract { impl PipelineElement for Subtract {
fn runner(&self) -> fn(&Inputs) -> Outputs { fn runner(&self) -> fn(&Inputs) -> Outputs {
|input| { |input| {
let [DataRef::Int(i0), DataRef::Int(i1), ..] = input.inner()[..] else { let [Data::Int(i0), Data::Int(i1), ..] = input.0[..] else {
panic!("Invalid data passed") panic!("Invalid data passed")
}; };
(i0 + i1).into() (i0 + i1).into()
@ -54,7 +54,7 @@ pub struct Stringify;
impl PipelineElement for Stringify { impl PipelineElement for Stringify {
fn runner(&self) -> fn(&Inputs) -> Outputs { fn runner(&self) -> fn(&Inputs) -> Outputs {
|input| { |input| {
let [DataRef::Int(int), ..] = input.inner()[..] else { let [Data::Int(int), ..] = input.0[..] else {
panic!("Invalid data passed") panic!("Invalid data passed")
}; };
int.to_string().into() int.to_string().into()

View file

@ -2,7 +2,7 @@
use crate::experimental::trait_based::{ use crate::experimental::trait_based::{
data::{ data::{
io::{Inputs, Outputs}, io::{Inputs, Outputs},
raw::DataRef, raw::Data,
}, },
element::{DataType, ElementSignature, PipelineElement}, element::{DataType, ElementSignature, PipelineElement},
}; };
@ -12,7 +12,7 @@ pub struct Concatenate(pub String);
impl PipelineElement for Concatenate { impl PipelineElement for Concatenate {
fn runner(&self) -> fn(&Inputs) -> Outputs { fn runner(&self) -> fn(&Inputs) -> Outputs {
|input| { |input| {
let [DataRef::String(s0), DataRef::String(s1), ..] = input.inner()[..] else { let [Data::String(s0), Data::String(s1), ..] = input.0[..] else {
panic!("Invalid data passed") panic!("Invalid data passed")
}; };
format!("{s0}{s1}").into() format!("{s0}{s1}").into()
@ -32,7 +32,7 @@ pub struct Upper;
impl PipelineElement for Upper { impl PipelineElement for Upper {
fn runner(&self) -> fn(&Inputs) -> Outputs { fn runner(&self) -> fn(&Inputs) -> Outputs {
|input| { |input| {
let [DataRef::String(s), ..] = input.inner()[..] else { let [Data::String(s), ..] = input.0[..] else {
panic!("Invalid data passed") panic!("Invalid data passed")
}; };
s.to_uppercase().into() s.to_uppercase().into()
@ -52,7 +52,7 @@ pub struct Lower;
impl PipelineElement for Lower { impl PipelineElement for Lower {
fn runner(&self) -> fn(&Inputs) -> Outputs { fn runner(&self) -> fn(&Inputs) -> Outputs {
|input| { |input| {
let [DataRef::String(s), ..] = input.inner()[..] else { let [Data::String(s), ..] = input.0[..] else {
panic!("Invalid data passed") panic!("Invalid data passed")
}; };
s.to_lowercase().into() s.to_lowercase().into()