use super::Result;
use super::{Error, Kind};
use std::collections::HashMap;
use std::str::FromStr;
use std;
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct VideoResponse {
success: bool,
#[serde(default)]
error: Option<String>,
id: String,
#[serde(default)]
status: Option<String>,
#[serde(default, rename="downloadTotal", skip_serializing_if = "Option::is_none")]
download_total: Option<i64>,
#[serde(default, rename="downloadComplete", skip_serializing_if = "Option::is_none")]
download_complete: Option<i64>,
#[serde(default, rename="downloadCompleteEstimate", skip_serializing_if = "Option::is_none")]
download_complete_estimate: Option<String>,
#[serde(default, rename="framesCount", skip_serializing_if = "Option::is_none")]
frames_count: Option<isize>,
#[serde(default, rename="framesComplete", skip_serializing_if = "Option::is_none")]
frames_complete: Option<isize>,
#[serde(default, rename="lastFrameBase64", skip_serializing_if = "Option::is_none")]
last_frame_base64: Option<String>,
#[serde(default, rename="millisecondsComplete", skip_serializing_if = "Option::is_none")]
milliseconds_complete: Option<isize>,
#[serde(default)]
expires: Option<String>,
}
#[derive(Debug, PartialEq)]
pub enum Status {
Pending,
Downloading,
Processing,
Complete,
Failed,
Unknown,
}
impl FromStr for Status {
type Err = ();
fn from_str(s: &str) -> std::result::Result<Self, <Self as FromStr>::Err> {
match s {
"pending" => Ok(Status::Pending),
"downloading" => Ok(Status::Downloading),
"processing" => Ok(Status::Processing),
"complete" => Ok(Status::Complete),
"failed" => Ok(Status::Failed),
"unknown" => Ok(Status::Unknown),
_ => Err(())
}
}
}
pub struct Video {
pub id: String,
pub status: Status,
pub download_total: i64,
pub download_complete: i64,
pub download_complete_estimate: String,
pub frames_count: isize,
pub frames_complete: isize,
pub last_frame_base64: String,
pub milliseconds_complete: isize,
pub expires: String,
}
impl Into<Result<Video>> for VideoResponse {
fn into(self) -> Result<Video> {
if self.success {
let st = self.status.unwrap_or("unknown".to_owned());
Ok(Video {
id: self.id,
status: Status::from_str(&st).unwrap(),
download_total: self.download_total.unwrap_or(0),
download_complete: self.download_complete.unwrap_or(0),
download_complete_estimate: self.download_complete_estimate.unwrap_or("unknown".to_owned()),
frames_count: self.frames_count.unwrap_or(0),
frames_complete: self.frames_complete.unwrap_or(0),
last_frame_base64: self.last_frame_base64.unwrap_or("".to_owned()),
milliseconds_complete: self.milliseconds_complete.unwrap_or(0),
expires: self.expires.unwrap_or("".to_owned())
})
} else {
let s = match self.error {
Some(s) => s,
None => "Request failed".to_owned(),
};
Err(Error {
kind: Kind::Machinebox(s),
})
}
}
}
pub struct CheckOptions {
kvs: HashMap<String, String>
}
impl IntoIterator for CheckOptions {
type Item = (String,String);
type IntoIter = ::std::collections::hash_map::IntoIter<String,String>;
fn into_iter(self) -> Self::IntoIter {
self.kvs.into_iter()
}
}
pub struct CheckOptionsBuilder {
kvs: HashMap<String, String>,
}
impl CheckOptionsBuilder {
pub fn new() -> Self {
CheckOptionsBuilder {
kvs: HashMap::new(),
}
}
pub fn result_duration(mut self, duration: &str) -> Self {
self.kvs.insert("resultDuration".to_owned(), duration.to_owned());
self
}
pub fn skip_frames(mut self, frames: isize) -> Self {
self.kvs.insert("skipframes".to_owned(), frames.to_string());
self
}
pub fn skip_seconds(mut self, seconds: isize) -> Self {
self.kvs.insert("skipseconds".to_owned(), seconds.to_string());
self
}
pub fn frame_width(mut self, width: isize) -> Self {
self.kvs.insert("frameWidth".to_owned(), width.to_string());
self
}
pub fn frame_height(mut self, height:isize) -> Self {
self.kvs.insert("frameHeight".to_owned(), height.to_string());
self
}
pub fn frame_concurrency(mut self, concurrency: isize) -> Self {
self.kvs.insert("frameConcurrency".to_owned(), concurrency.to_string());
self
}
pub fn facebox_threshold(mut self, threshold: f64) -> Self {
self.kvs.insert("faceboxThreshold".to_owned(), threshold.to_string());
self
}
pub fn tagbox_include(mut self, include: &str) -> Self {
self.kvs.insert("tagboxInclude".to_owned(), include.to_owned());
self
}
pub fn tagbox_threshold(mut self, threshold: f64) -> Self {
self.kvs.insert("tagboxThreshold".to_owned(), threshold.to_string());
self
}
pub fn nudebox_threshold(mut self, threshold: f64) -> Self {
self.kvs.insert("nudeboxThreshold".to_owned(), threshold.to_string());
self
}
pub fn finish(self) -> CheckOptions {
CheckOptions {
kvs: self.kvs
}
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Item {
pub key: String,
#[serde(default)]
pub instances: Vec<Range>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Range {
pub start: isize,
pub end: isize,
pub start_ms: isize,
pub end_ms: isize,
#[serde(default)]
pub confidence: Option<f64>
}
#[derive(Serialize, Deserialize, Debug)]
pub struct VideoAnalysisResponse {
success: bool,
#[serde(default)]
error: Option<String>,
ready: bool,
#[serde(default)]
facebox: Option<Facebox>,
#[serde(default)]
tagbox: Option<Tagbox>,
#[serde(default)]
nudebox: Option<Nudebox>,
}
impl Into<Result<VideoAnalysis>> for VideoAnalysisResponse {
fn into(self) -> Result<VideoAnalysis> {
if self.success {
Ok(VideoAnalysis{
ready: self.ready,
facebox: self.facebox,
tagbox: self.tagbox,
nudebox: self.nudebox
})
} else {
let s = match self.error {
Some(s) => s,
None => "Request failed".to_owned(),
};
Err(Error {
kind: Kind::Machinebox(s),
})
}
}
}
pub struct VideoAnalysis {
pub ready: bool,
pub facebox: Option<Facebox>,
pub tagbox: Option<Tagbox>,
pub nudebox: Option<Nudebox>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Facebox {
pub faces: Vec<Item>,
#[serde(rename = "errorsCount")]
pub errors_count: isize,
#[serde(default, rename = "lastError")]
pub last_error: Option<String>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Tagbox {
pub tags: Vec<Item>,
#[serde(rename = "errorsCount")]
pub error_count: isize,
#[serde(rename = "lastError", default)]
pub last_error: Option<String>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Nudebox {
pub nudity: Vec<Item>,
#[serde(rename = "errorsCount")]
pub error_count: isize,
#[serde(rename = "lastError", default)]
pub last_error: Option<String>,
}