use std::ops::Index;
use eye_hal::control::Descriptor as ControlDescriptor;
use eye_hal::control::State as ControlState;
use eye_hal::error::{Error, ErrorKind, Result};
use eye_hal::platform::Context as PlatformContext;
use eye_hal::platform::{Device as PlatformDevice, Stream as PlatformStream};
use eye_hal::stream::Descriptor as StreamDescriptor;
use eye_hal::traits::{Context, Device as DeviceTrait, Stream as StreamTrait};
use crate::colorconvert;
pub struct Device<'a> {
pub hal: Box<dyn DeviceTrait<'a> + 'a>,
}
impl<'a> Device<'a> {
fn new(hal: impl DeviceTrait<'a> + 'a + Send) -> Result<Self> {
let cc = colorconvert::Device::new(PlatformDevice::Custom(Box::new(hal)))?;
Ok(Device { hal: Box::new(cc) })
}
pub fn with_index(index: usize) -> Result<Self> {
let ctx = PlatformContext::default();
let devices = ctx.devices()?;
let uri = if let Some(desc) = devices.get(index) {
&desc.uri
} else {
return Err(Error::new(ErrorKind::Other, "invalid index"));
};
let hal = ctx.open_device(uri)?;
Self::new(hal)
}
pub fn with_uri<S: AsRef<str>>(uri: S) -> Result<Self> {
let uri = uri.as_ref();
let ctx = PlatformContext::default();
let hal = ctx.open_device(uri)?;
Self::new(hal)
}
pub fn streams(&'a self) -> Result<impl Iterator<Item=Stream<'a>>> {
let streams = self.hal.streams()?;
Ok(Streams {
dev: &*self.hal,
streams,
})
}
pub fn controls(&'a self) -> Result<Controls<&dyn DeviceTrait>> {
let descs = self.hal.controls()?;
Ok(Controls {
dev: &*self.hal,
descs,
})
}
pub fn controls_mut(&'a mut self) -> Result<Controls<&mut dyn DeviceTrait>> {
let descs = self.hal.controls()?;
Ok(Controls {
dev: &mut *self.hal,
descs,
})
}
}
pub struct Streams<'a> {
dev: &'a dyn DeviceTrait<'a>,
streams: Vec<StreamDescriptor>,
index: usize,
}
impl<'a> Streams<'a> {
pub fn filter<P>(self, predicate: P) -> Self
where
P: FnMut(&StreamDescriptor) -> bool,
{
Streams {
dev: self.dev,
streams: self.streams.into_iter().filter(predicate).collect(),
index: 0,
}
}
pub fn reduce<F>(self, f: F) -> Option<Stream<'a>>
where
F: FnMut(StreamDescriptor, StreamDescriptor) -> StreamDescriptor,
{
match self.streams.into_iter().reduce(f) {
Some(desc) => Some(Stream {
dev: self.dev,
desc,
}),
None => None,
}
}
}
impl<'a> Iterator for Streams<'a> {
type Item = Stream<'a>;
fn next(&mut self) -> Option<Self::Item> {
if self.index >= self.streams.len() {
None
} else {
Some(self.streams.remove(0))
}
}
}
pub struct Stream<'a> {
dev: &'a dyn DeviceTrait<'a>,
desc: StreamDescriptor,
}
impl<'a> Stream<'a> {
pub fn start(self) -> Result<impl StreamTrait<'a>> {
self.dev.start_stream(&self.desc)
}
}
pub struct Controls<D> {
dev: D,
descs: Vec<ControlDescriptor>,
}
impl<'a, D> Controls<D>
where
D: AsRef<dyn DeviceTrait<'a>>,
{
pub fn filter<P>(self, predicate: P) -> Self
where
P: FnMut(&ControlDescriptor) -> bool,
{
Controls {
dev: self.dev,
descs: self.descs.into_iter().filter(predicate).collect(),
}
}
pub fn find<P>(self, predicate: P) -> Option<Control<D>>
where
P: FnMut(&ControlDescriptor) -> bool,
{
match self.descs.into_iter().find(predicate) {
Some(desc) => Some(Control {
dev: self.dev,
desc,
}),
None => None,
}
}
}
impl<'a, D> Controls<D>
where
D: AsMut<dyn DeviceTrait<'a>>,
{
pub fn find_mut<P>(self, predicate: P) -> Option<Control<D>>
where
P: FnMut(&ControlDescriptor) -> bool,
{
match self.descs.into_iter().find(predicate) {
Some(desc) => Some(Control {
dev: self.dev,
desc,
}),
None => None,
}
}
}
pub struct Control<D> {
dev: D,
desc: ControlDescriptor,
}
impl<'a, D> Control<D>
where
D: AsRef<dyn DeviceTrait<'a>>,
{
pub fn read(&self) -> Result<ControlState> {
self.dev.as_ref().control(self.desc.id)
}
}
impl<'a, D> Control<D>
where
D: AsMut<dyn DeviceTrait<'a>>,
{
pub fn write(&mut self, state: ControlState) -> Result<()> {
self.dev.as_mut().set_control(self.desc.id, &state)
}
}