1use super::net_handle;
5pub use crate::wire::{WebcamStatus, WebcamStream};
6
7pub(crate) mod ops {
8 use serde_json::json;
9
10 use crate::error::Result;
11 use crate::wire::{
12 net_command, value_as, CommandResponse, Op, Timeout, WebcamStatus, WebcamStream,
13 };
14
15 const ROLE: &str = "webcam";
16
17 fn parse_stopped(resp: CommandResponse) -> Result<bool> {
18 let status: WebcamStopped = value_as(resp)?;
19 Ok(status.stopped)
20 }
21
22 #[derive(serde::Deserialize)]
23 struct WebcamStopped {
24 #[serde(default)]
25 stopped: bool,
26 }
27
28 fn parse_url(resp: CommandResponse) -> Result<Option<String>> {
29 let status: WebcamStatus = value_as(resp)?;
30 Ok(status.url)
31 }
32
33 pub(crate) fn start(name: &str) -> Op<WebcamStream> {
34 Op {
35 req: net_command(
37 name,
38 ROLE,
39 "start",
40 json!({}),
41 Timeout::After(std::time::Duration::from_secs(30)),
42 ),
43 parse: value_as::<WebcamStream>,
44 }
45 }
46
47 pub(crate) fn stop(name: &str) -> Op<bool> {
48 Op {
49 req: net_command(name, ROLE, "stop", json!({}), Timeout::Default),
50 parse: parse_stopped,
51 }
52 }
53
54 pub(crate) fn status(name: &str) -> Op<WebcamStatus> {
55 Op {
56 req: net_command(name, ROLE, "status", json!({}), Timeout::Default),
57 parse: value_as::<WebcamStatus>,
58 }
59 }
60
61 pub(crate) fn url(name: &str) -> Op<Option<String>> {
62 Op {
63 req: net_command(name, ROLE, "url", json!({}), Timeout::Default),
64 parse: parse_url,
65 }
66 }
67}
68
69net_handle! {
70 sync: Webcam,
75 async: AsyncWebcam,
76 methods: {
77 fn start() -> WebcamStream = ops::start;
80 fn stop() -> bool = ops::stop;
82 fn status() -> WebcamStatus = ops::status;
84 fn url() -> Option<String> = ops::url;
86 }
87}