cat_dev/mion/cgis/
signal_get.rs

1//! API's for interacting with `/signal_get.cgi`, an HTTP interface for
2//! getting signals
3
4use crate::{
5	errors::NetworkError,
6	mion::{cgis::do_simple_request, proto::cgis::MIONCGIErrors},
7};
8use reqwest::{Client, Method};
9use serde::Serialize;
10use std::net::Ipv4Addr;
11
12/// Perform a `signal_get` request for the `VDD2` signal given a host.
13///
14/// ## Errors
15///
16/// - If we cannot encode the parameters as a form url encoded.
17/// - If we cannot make the HTTP request.
18/// - If the server does not respond with a 200.
19/// - If we cannot read the body from HTTP.
20/// - If we cannot parse the HTML response.
21pub async fn get_vdd2(mion_ip: Ipv4Addr) -> Result<String, NetworkError> {
22	get_vdd2_with_raw_client(&Client::default(), mion_ip).await
23}
24
25/// Perform a `signal_get` request for the `VDD2` signal given a host,
26/// but with an already existing HTTP client.
27///
28/// ## Errors
29///
30/// - If we cannot encode the parameters as a form url encoded.
31/// - If we cannot make the HTTP request.
32/// - If the server does not respond with a 200.
33/// - If we cannot read the body from HTTP.
34/// - If we cannot parse the HTML response.
35pub async fn get_vdd2_with_raw_client(
36	client: &Client,
37	mion_ip: Ipv4Addr,
38) -> Result<String, NetworkError> {
39	let body_as_string = do_raw_signal_http_request(client, mion_ip, &[("sig", "VDD2")]).await?;
40
41	let start_tag_location = body_as_string
42		.find("<body>")
43		.map(|num| num + 6)
44		.ok_or_else(|| MIONCGIErrors::HtmlResponseMissingBody(body_as_string.clone()))?;
45	let body_without_start_tag = body_as_string.split_at(start_tag_location).1;
46	let end_tag_location = body_without_start_tag
47		.find("</body>")
48		.ok_or_else(|| MIONCGIErrors::HtmlResponseMissingBody(body_as_string.clone()))?;
49
50	Ok(body_without_start_tag
51		.split_at(end_tag_location)
52		.0
53		.to_owned())
54}
55
56/// Perform a raw operation on the MION board's `control.cgi` page.
57///
58/// *note: you probably want to call one of the actual methods, as this is
59/// basically just a thin wrapper around an HTTP Post Request. Not doing much
60/// else more. A lot of it requires that you set things up correctly.*
61///
62/// ## Errors
63///
64/// - If we cannot make an HTTP request to the MION Request.
65/// - If we fail to encode your parameters into a request body.
66pub async fn do_raw_signal_http_request<UrlEncodableType>(
67	client: &Client,
68	mion_ip: Ipv4Addr,
69	url_parameters: UrlEncodableType,
70) -> Result<String, NetworkError>
71where
72	UrlEncodableType: Serialize,
73{
74	do_simple_request::<String>(
75		client,
76		Method::POST,
77		format!("http://{mion_ip}/signal_get.cgi"),
78		Some(
79			serde_urlencoded::to_string(&url_parameters)
80				.map_err(MIONCGIErrors::FormDataEncodeError)?,
81		),
82	)
83	.await
84}