mirror of
https://github.com/l1npengtul/nokhwa.git
synced 2026-07-04 10:37:26 +00:00
ergonomic changes to trait
This commit is contained in:
+17
-11
@@ -1,9 +1,10 @@
|
|||||||
use crate::error::{NokhwaError};
|
use crate::control::{ControlDescription, ControlId, ControlValue, Controls};
|
||||||
|
use crate::error::NokhwaError;
|
||||||
use crate::frame_format::FrameFormat;
|
use crate::frame_format::FrameFormat;
|
||||||
use crate::control::{ControlId, ControlValue, Controls};
|
|
||||||
use crate::types::{CameraFormat, FrameRate, Resolution};
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use crate::stream::Stream;
|
use crate::stream::Stream;
|
||||||
|
use crate::types::{CameraFormat, FrameRate, Resolution};
|
||||||
|
use std::collections::hash_map::{Keys, Values};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub trait Setting {
|
pub trait Setting {
|
||||||
fn enumerate_formats(&self) -> Result<Vec<CameraFormat>, NokhwaError>;
|
fn enumerate_formats(&self) -> Result<Vec<CameraFormat>, NokhwaError>;
|
||||||
@@ -15,15 +16,20 @@ pub trait Setting {
|
|||||||
|
|
||||||
fn set_format(&self, camera_format: CameraFormat) -> Result<(), NokhwaError>;
|
fn set_format(&self, camera_format: CameraFormat) -> Result<(), NokhwaError>;
|
||||||
|
|
||||||
fn controls(&self) -> &Controls;
|
fn control_ids(&self) -> Keys<ControlId, ControlDescription>;
|
||||||
|
|
||||||
|
fn control_descriptions(&self) -> Values<ControlId, ControlDescription>;
|
||||||
|
|
||||||
|
fn control_values(&self) -> Values<ControlId, ControlValue>;
|
||||||
|
|
||||||
|
fn control_value(&self, id: &ControlId) -> Option<&ControlValue>;
|
||||||
|
|
||||||
|
fn control_description(&self, id: &ControlId) -> Option<&ControlDescription>;
|
||||||
|
|
||||||
|
fn set_control(&mut self, property: &ControlId, value: ControlValue)
|
||||||
|
-> Result<(), NokhwaError>;
|
||||||
|
|
||||||
fn refresh_controls(&mut self) -> Result<(), NokhwaError>;
|
fn refresh_controls(&mut self) -> Result<(), NokhwaError>;
|
||||||
|
|
||||||
fn set_control(
|
|
||||||
&mut self,
|
|
||||||
property: &ControlId,
|
|
||||||
value: ControlValue,
|
|
||||||
) -> Result<(), NokhwaError>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "async")]
|
#[cfg(feature = "async")]
|
||||||
|
|||||||
+212
-184
@@ -1,9 +1,10 @@
|
|||||||
|
use crate::error::{NokhwaError, NokhwaResult};
|
||||||
|
use crate::ranges::{Range, ValidatableRange};
|
||||||
|
use ordered_float::OrderedFloat;
|
||||||
|
use std::collections::hash_map::{Keys, Values};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use ordered_float::OrderedFloat;
|
|
||||||
use crate::error::{NokhwaError, NokhwaResult};
|
|
||||||
use crate::ranges::{Range, ValidatableRange};
|
|
||||||
|
|
||||||
pub type PlatformSpecificControlId = u64;
|
pub type PlatformSpecificControlId = u64;
|
||||||
|
|
||||||
@@ -42,7 +43,7 @@ pub enum ControlId {
|
|||||||
|
|
||||||
Orientation,
|
Orientation,
|
||||||
|
|
||||||
PlatformSpecific(PlatformSpecificControlId)
|
PlatformSpecific(PlatformSpecificControlId),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for ControlId {
|
impl Display for ControlId {
|
||||||
@@ -53,49 +54,125 @@ impl Display for ControlId {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, Default, PartialEq)]
|
#[derive(Clone, Debug, Default, PartialEq)]
|
||||||
pub struct Controls {
|
pub struct Controls {
|
||||||
controls: HashMap<ControlId, ControlBody>,
|
descriptions: HashMap<ControlId, ControlDescription>,
|
||||||
values: HashMap<ControlId, ControlId>,
|
values: HashMap<ControlId, ControlValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Controls {
|
impl Controls {
|
||||||
pub fn new(device_controls: HashMap<ControlId, ControlBody>) -> Self {
|
/// INVARIANTS: All `ControlId` in `device_values` MUST exist in `device_controls`
|
||||||
Self {
|
pub fn new(
|
||||||
controls: device_controls,
|
device_controls: HashMap<ControlId, ControlDescription>,
|
||||||
|
device_values: HashMap<ControlId, ControlValue>,
|
||||||
|
) -> Option<Self> {
|
||||||
|
for (id, value) in device_values.iter() {
|
||||||
|
if let Some(description) = device_controls.get(id) {
|
||||||
|
if !description.validate(value) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some(Self {
|
||||||
|
descriptions: device_controls,
|
||||||
|
values: device_values,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn empty() -> Self {
|
pub fn empty() -> Self {
|
||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn control_value(&self, control_id: &ControlId) -> Option<&ControlBody> {
|
pub fn unchecked_new(
|
||||||
self.controls.get(control_id)
|
device_controls: HashMap<ControlId, ControlDescription>,
|
||||||
|
device_values: HashMap<ControlId, ControlValue>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
descriptions: device_controls,
|
||||||
|
values: device_values,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_control_value(&mut self, control_id: &ControlId, value: ControlValue) -> NokhwaResult<()> {
|
pub fn description(&self, control_id: &ControlId) -> Option<&ControlDescription> {
|
||||||
|
self.descriptions.get(control_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn value(&self, control_id: &ControlId) -> Option<&ControlValue> {
|
||||||
|
self.values.get(control_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn descriptions(&self) -> Values<ControlId, ControlDescription> {
|
||||||
|
self.descriptions.values()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn values(&self) -> Values<ControlId, ControlValue> {
|
||||||
|
self.values.values()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ids(&self) -> Keys<ControlId, ControlDescription> {
|
||||||
|
self.descriptions.keys()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_control_value(
|
||||||
|
&mut self,
|
||||||
|
control_id: &ControlId,
|
||||||
|
value: ControlValue,
|
||||||
|
) -> NokhwaResult<()> {
|
||||||
// see if it exists
|
// see if it exists
|
||||||
if let Some(control) = self.controls.get_mut(control_id) {
|
if let None = self.descriptions.get(control_id) {
|
||||||
// FIXME: Remove this clone one day!
|
return Err(NokhwaError::SetPropertyError {
|
||||||
control.set_value(value.clone())?;
|
property: control_id.to_string(),
|
||||||
|
value: value.to_string(),
|
||||||
|
error: "ID Not Found".to_string(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.values.get_mut(control_id) {
|
||||||
|
Some(old) => {
|
||||||
|
*old = value;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
// this should not happen,
|
||||||
|
None => Err(NokhwaError::SetPropertyError {
|
||||||
|
property: control_id.to_string(),
|
||||||
|
value: value.to_string(),
|
||||||
|
error: "If you got this, its probably a bug or your camera is _horribly_ bugged :>"
|
||||||
|
.to_string(),
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
Err(NokhwaError::SetPropertyError {
|
|
||||||
property: control_id.to_string(),
|
|
||||||
value: value.to_string(),
|
|
||||||
error: "Not Found/Not Supported".to_string(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct ControlBody {
|
pub struct ControlDescription {
|
||||||
flags: HashSet<ControlFlags>,
|
flags: HashSet<ControlFlags>,
|
||||||
descriptor: ControlValueDescriptor,
|
descriptor: ControlValueDescriptor,
|
||||||
default_value: Option<ControlValue>,
|
default_value: Option<ControlValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ControlBody {
|
impl ControlDescription {
|
||||||
pub fn new(control_flags: HashSet<ControlFlags>, control_value_descriptor: ControlValueDescriptor, default_value: Option<ControlValue>) -> Self {
|
pub fn new(
|
||||||
|
control_flags: HashSet<ControlFlags>,
|
||||||
|
control_value_descriptor: ControlValueDescriptor,
|
||||||
|
default_value: Option<ControlValue>,
|
||||||
|
) -> Option<Self> {
|
||||||
|
if let Some(default) = &default_value {
|
||||||
|
if !control_value_descriptor.validate(default) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(Self {
|
||||||
|
flags: control_flags,
|
||||||
|
descriptor: control_value_descriptor,
|
||||||
|
default_value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_unchecked(
|
||||||
|
control_flags: HashSet<ControlFlags>,
|
||||||
|
control_value_descriptor: ControlValueDescriptor,
|
||||||
|
default_value: Option<ControlValue>,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
flags: control_flags,
|
flags: control_flags,
|
||||||
descriptor: control_value_descriptor,
|
descriptor: control_value_descriptor,
|
||||||
@@ -122,6 +199,10 @@ impl ControlBody {
|
|||||||
pub fn remove_flag(&mut self, flag: ControlFlags) -> bool {
|
pub fn remove_flag(&mut self, flag: ControlFlags) -> bool {
|
||||||
self.flags.remove(&flag)
|
self.flags.remove(&flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn validate(&self, value: &ControlValue) -> bool {
|
||||||
|
self.descriptor.validate(value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
|
||||||
@@ -160,6 +241,10 @@ pub enum ControlValueDescriptor {
|
|||||||
width_limits: Range<i64>,
|
width_limits: Range<i64>,
|
||||||
height_limits: Range<i64>,
|
height_limits: Range<i64>,
|
||||||
},
|
},
|
||||||
|
// An Orientation
|
||||||
|
// Usually, this is a read-only value.
|
||||||
|
// An empty vec indicates any allowed value.
|
||||||
|
Orientation(Vec<Orientation>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ControlValueDescriptor {
|
impl ControlValueDescriptor {
|
||||||
@@ -167,166 +252,66 @@ impl ControlValueDescriptor {
|
|||||||
match self {
|
match self {
|
||||||
ControlValueDescriptor::Null => {
|
ControlValueDescriptor::Null => {
|
||||||
if let &ControlValue::Null = value {
|
if let &ControlValue::Null = value {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ControlValueDescriptor::Integer(int_range) => {
|
ControlValueDescriptor::Integer(int_range) => {
|
||||||
if let ControlValue::Integer(i) = value {
|
if let ControlValue::Integer(i) = value {
|
||||||
return int_range.validate(i)
|
return int_range.validate(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ControlValueDescriptor::BitMask => {
|
ControlValueDescriptor::BitMask => {
|
||||||
if let &ControlValue::BitMask(_) = value {
|
if let &ControlValue::BitMask(_) = value {
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ControlValueDescriptor::Float(float_range) => {
|
ControlValueDescriptor::Float(float_range) => {
|
||||||
if let ControlValue::Float(i) = value {
|
if let ControlValue::Float(i) = value {
|
||||||
return float_range.validate(i)
|
return float_range.validate(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ControlValueDescriptor::String => {
|
ControlValueDescriptor::String => {
|
||||||
if let &ControlValue::String(_) = value {
|
if let &ControlValue::String(_) = value {
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ControlValueDescriptor::Boolean => {
|
ControlValueDescriptor::Boolean => {
|
||||||
if let &ControlValue::Boolean(_) = value {
|
if let &ControlValue::Boolean(_) = value {
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ControlValueDescriptor::Array(arr) => {
|
ControlValueDescriptor::Array(arr) => {
|
||||||
if let &ControlValue::Array(_) = value {
|
if let &ControlValue::Array(_) = value {
|
||||||
return arr.is_valid_value(value)
|
return arr.is_valid_value(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ControlValueDescriptor::Binary(size_limits) => {
|
ControlValueDescriptor::Binary(size_limits) => {
|
||||||
if let ControlValue::Binary(bin) = value {
|
if let ControlValue::Binary(bin) = value {
|
||||||
return size_limits.validate(bin.len() as u64)
|
return size_limits.validate(bin.len() as u64);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ControlValueDescriptor::Menu(choices) => {
|
ControlValueDescriptor::Menu(choices) => {
|
||||||
if let ControlValue::EnumPick(choice) = value {
|
if let ControlValue::EnumPick(choice) = value {
|
||||||
return choices.contains_key(choice)
|
return choices.contains_key(choice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ControlValueDescriptor::Area { width_limits, height_limits } => {
|
ControlValueDescriptor::Area {
|
||||||
|
width_limits,
|
||||||
|
height_limits,
|
||||||
|
} => {
|
||||||
if let ControlValue::Area { width, height } = &value {
|
if let ControlValue::Area { width, height } = &value {
|
||||||
return width_limits.validate(width) && height_limits.validate(height)
|
return width_limits.validate(width) && height_limits.validate(height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ControlValueDescriptor::Orientation(orientations) => {
|
||||||
|
if let ControlValue::Orientation(orientation) = &value {
|
||||||
|
return orientations.contains(orientation) || orientations.is_empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// #[derive(Clone, Debug, PartialEq)]
|
|
||||||
// pub enum ControlValuePrimitiveDescriptor {
|
|
||||||
// Null,
|
|
||||||
// Integer(Range<i64>),
|
|
||||||
// BitMask,
|
|
||||||
// Float(Range<f64>),
|
|
||||||
// String,
|
|
||||||
// Binary,
|
|
||||||
// Boolean,
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// impl ControlValuePrimitiveDescriptor {
|
|
||||||
// pub fn is_valid_primitive_value(&self, other: &ControlValuePrimitive) -> bool {
|
|
||||||
// match self {
|
|
||||||
// ControlValuePrimitiveDescriptor::Null => {
|
|
||||||
// if let ControlValuePrimitive::Null = other {
|
|
||||||
// return true
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ControlValuePrimitiveDescriptor::Integer(i) => {
|
|
||||||
// if let ControlValuePrimitive::Integer(v) = other {
|
|
||||||
// return i.validate(v)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ControlValuePrimitiveDescriptor::BitMask => {
|
|
||||||
// if let ControlValuePrimitive::BitMask(_) = other {
|
|
||||||
// return true
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ControlValuePrimitiveDescriptor::Float(f) => {
|
|
||||||
// if let ControlValuePrimitive::Float(v) = other {
|
|
||||||
// return f.validate(v)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ControlValuePrimitiveDescriptor::String => {
|
|
||||||
// if let ControlValuePrimitive::String(_) = other {
|
|
||||||
// return true
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ControlValuePrimitiveDescriptor::Boolean => {
|
|
||||||
// if let ControlValuePrimitive::Boolean(_) = other {
|
|
||||||
// return true
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// false
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// pub fn is_valid_value(&self, other: &ControlValue) -> bool {
|
|
||||||
// match self {
|
|
||||||
// ControlValuePrimitiveDescriptor::Null => {
|
|
||||||
// if let ControlValue::Null = other {
|
|
||||||
// return true
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ControlValuePrimitiveDescriptor::Integer(i) => {
|
|
||||||
// if let ControlValue::Integer(v) = other {
|
|
||||||
// return i.validate(v)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ControlValuePrimitiveDescriptor::BitMask => {
|
|
||||||
// if let ControlValue::BitMask(_) = other {
|
|
||||||
// return true
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ControlValuePrimitiveDescriptor::Float(f) => {
|
|
||||||
// if let ControlValue::Float(v) = other {
|
|
||||||
// return f.validate(v)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ControlValuePrimitiveDescriptor::String => {
|
|
||||||
// if let ControlValue::String(_) = other {
|
|
||||||
// return true
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ControlValuePrimitiveDescriptor::Boolean => {
|
|
||||||
// if let ControlValue::Boolean(_) = other {
|
|
||||||
// return true
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// false
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// #[derive(Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
|
|
||||||
// pub enum ControlValuePrimitive {
|
|
||||||
// Null,
|
|
||||||
// Integer(i64),
|
|
||||||
// BitMask(i64),
|
|
||||||
// Float(OrderedFloat<f64>),
|
|
||||||
// String(String),
|
|
||||||
// Boolean(bool),
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// impl From<ControlValuePrimitive> for ControlValue {
|
|
||||||
// fn from(value: ControlValuePrimitive) -> Self {
|
|
||||||
// match value {
|
|
||||||
// ControlValuePrimitive::Null => ControlValue::Null,
|
|
||||||
// ControlValuePrimitive::Integer(i) => ControlValue::Integer(i),
|
|
||||||
// ControlValuePrimitive::BitMask(b) => ControlValue::BitMask(b),
|
|
||||||
// ControlValuePrimitive::Float(f) => ControlValue::Float(f),
|
|
||||||
// ControlValuePrimitive::String(s) => ControlValue::String(s),
|
|
||||||
// ControlValuePrimitive::Boolean(b) => ControlValue::Boolean(b),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Hash, Eq, PartialEq, PartialOrd)]
|
#[derive(Clone, Debug, Hash, Eq, PartialEq, PartialOrd)]
|
||||||
pub enum ControlValue {
|
pub enum ControlValue {
|
||||||
@@ -339,23 +324,22 @@ pub enum ControlValue {
|
|||||||
Array(Vec<ControlValue>),
|
Array(Vec<ControlValue>),
|
||||||
Binary(Vec<u8>),
|
Binary(Vec<u8>),
|
||||||
EnumPick(Box<ControlValue>),
|
EnumPick(Box<ControlValue>),
|
||||||
Area {
|
Area { width: i64, height: i64 },
|
||||||
width: i64,
|
Orientation(Orientation),
|
||||||
height: i64,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ControlValue {
|
impl ControlValue {
|
||||||
pub fn is_primitive(&self) -> bool {
|
pub fn is_primitive(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
ControlValue::Null |
|
ControlValue::Null
|
||||||
ControlValue::Integer(_) |
|
| ControlValue::Integer(_)
|
||||||
ControlValue::BitMask(_) |
|
| ControlValue::BitMask(_)
|
||||||
ControlValue::Float(_) |
|
| ControlValue::Float(_)
|
||||||
ControlValue::String(_)|
|
| ControlValue::String(_)
|
||||||
ControlValue::Boolean(_) |
|
| ControlValue::Boolean(_)
|
||||||
ControlValue::Binary(_) |
|
| ControlValue::Binary(_)
|
||||||
ControlValue::Area { .. } => true,
|
| ControlValue::Area { .. }
|
||||||
|
| ControlValue::Orientation(_) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -383,39 +367,61 @@ impl ControlValue {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ControlValue::Integer(_) => {if let ControlValue::Integer(_) = other {
|
ControlValue::Integer(_) => {
|
||||||
return true;
|
if let ControlValue::Integer(_) = other {
|
||||||
}}
|
return true;
|
||||||
ControlValue::BitMask(_) => {if let ControlValue::BitMask(_) = other {
|
}
|
||||||
return true;
|
}
|
||||||
}}
|
ControlValue::BitMask(_) => {
|
||||||
ControlValue::Float(_) => {if let ControlValue::Float(_) = other {
|
if let ControlValue::BitMask(_) = other {
|
||||||
return true;
|
return true;
|
||||||
}}
|
}
|
||||||
ControlValue::String(_) => {if let ControlValue::String(_) = other {
|
}
|
||||||
return true;
|
ControlValue::Float(_) => {
|
||||||
}}
|
if let ControlValue::Float(_) = other {
|
||||||
ControlValue::Boolean(_) => {if let ControlValue::Boolean(_) = other {
|
return true;
|
||||||
return true;
|
}
|
||||||
}}
|
}
|
||||||
ControlValue::Array(_) => {if let ControlValue::Array(_) = other {
|
ControlValue::String(_) => {
|
||||||
return true;
|
if let ControlValue::String(_) = other {
|
||||||
}}
|
return true;
|
||||||
ControlValue::EnumPick(_) => {if let ControlValue::EnumPick(_) = other {
|
}
|
||||||
return true;
|
}
|
||||||
}}
|
ControlValue::Boolean(_) => {
|
||||||
ControlValue::Binary(_) => {if let ControlValue::Binary(_) = other {
|
if let ControlValue::Boolean(_) = other {
|
||||||
return true;
|
return true;
|
||||||
}}
|
}
|
||||||
ControlValue::Area { .. } => {if let ControlValue::Area { .. } = other {
|
}
|
||||||
return true;
|
ControlValue::Array(_) => {
|
||||||
}}
|
if let ControlValue::Array(_) = other {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ControlValue::EnumPick(_) => {
|
||||||
|
if let ControlValue::EnumPick(_) = other {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ControlValue::Binary(_) => {
|
||||||
|
if let ControlValue::Binary(_) = other {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ControlValue::Area { .. } => {
|
||||||
|
if let ControlValue::Area { .. } = other {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ControlValue::Orientation(_) => {
|
||||||
|
if let ControlValue::Orientation(_) = other {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => return false,
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for ControlValue {
|
impl Display for ControlValue {
|
||||||
@@ -423,3 +429,25 @@ impl Display for ControlValue {
|
|||||||
write!(f, "Control Value: {self:?}")
|
write!(f, "Control Value: {self:?}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub enum Orientation {
|
||||||
|
User,
|
||||||
|
Environment,
|
||||||
|
Up,
|
||||||
|
Down,
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
Center,
|
||||||
|
Near,
|
||||||
|
Far,
|
||||||
|
Other,
|
||||||
|
Custom(i64),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Orientation {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "Orientation {self:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::fmt::{Display, Formatter};
|
|
||||||
use crate::camera::{AsyncCamera, Camera};
|
use crate::camera::{AsyncCamera, Camera};
|
||||||
use crate::error::NokhwaResult;
|
use crate::error::NokhwaResult;
|
||||||
use crate::types::{CameraIndex, CameraInformation};
|
use crate::types::{CameraIndex, CameraInformation};
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
|
||||||
pub enum Backends {
|
pub enum Backends {
|
||||||
@@ -10,7 +10,7 @@ pub enum Backends {
|
|||||||
AVFoundation,
|
AVFoundation,
|
||||||
MicrosoftMediaFoundation,
|
MicrosoftMediaFoundation,
|
||||||
OpenCV,
|
OpenCV,
|
||||||
Custom(&'static str)
|
Custom(&'static str),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Backends {
|
impl Display for Backends {
|
||||||
@@ -23,16 +23,15 @@ pub trait PlatformTrait {
|
|||||||
const PLATFORM: Backends;
|
const PLATFORM: Backends;
|
||||||
type Camera: Camera;
|
type Camera: Camera;
|
||||||
|
|
||||||
|
|
||||||
fn block_on_permission(&mut self) -> NokhwaResult<()>;
|
fn block_on_permission(&mut self) -> NokhwaResult<()>;
|
||||||
|
|
||||||
fn check_permission_given(&mut self) -> bool;
|
fn check_permission_given(&mut self) -> bool;
|
||||||
|
|
||||||
fn query(&mut self) -> NokhwaResult<Vec<CameraInformation>>;
|
fn query(&mut self) -> NokhwaResult<Vec<CameraInformation>>;
|
||||||
|
|
||||||
fn open(&mut self, index: &CameraIndex) -> NokhwaResult<Self::Camera>;
|
fn open(&mut self, index: CameraIndex) -> NokhwaResult<Self::Camera>;
|
||||||
|
|
||||||
fn open_dynamic(&mut self, index: &CameraIndex) -> NokhwaResult<Box<dyn Camera>> {
|
fn open_dynamic(&mut self, index: CameraIndex) -> NokhwaResult<Box<dyn Camera>> {
|
||||||
self.open(index).map(|cam| Box::new(cam))
|
self.open(index).map(|cam| Box::new(cam))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,15 +42,13 @@ pub trait AsyncPlatformTrait {
|
|||||||
const PLATFORM: Backends;
|
const PLATFORM: Backends;
|
||||||
type AsyncCamera: AsyncCamera;
|
type AsyncCamera: AsyncCamera;
|
||||||
|
|
||||||
|
|
||||||
async fn await_permission(&mut self) -> NokhwaResult<()>;
|
async fn await_permission(&mut self) -> NokhwaResult<()>;
|
||||||
|
|
||||||
async fn query_async(&mut self) -> NokhwaResult<Vec<CameraInformation>>;
|
async fn query_async(&mut self) -> NokhwaResult<Vec<CameraInformation>>;
|
||||||
|
|
||||||
async fn open_async (&mut self, index: &CameraIndex) -> NokhwaResult<Self::AsyncCamera>;
|
async fn open_async(&mut self, index: &CameraIndex) -> NokhwaResult<Self::AsyncCamera>;
|
||||||
|
|
||||||
|
|
||||||
async fn open_dynamic_async(&mut self, index: &CameraIndex) -> NokhwaResult<Box<dyn Camera>> {
|
async fn open_dynamic_async(&mut self, index: &CameraIndex) -> NokhwaResult<Box<dyn Camera>> {
|
||||||
self.open_async(index).await.map(|cam| Box::new(cam))
|
self.open_async(index).await.map(|cam| Box::new(cam))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user