Skip to content

Commit

Permalink
Raw request support
Browse files Browse the repository at this point in the history
  • Loading branch information
r12f committed Jul 13, 2022
1 parent a80d8b7 commit c5f7765
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 7 deletions.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,29 @@ pixoo.start_batch()
.execute().await.expect("Request should succeed.");
```

#### Sending raw requests

In case new API is released and we haven't support it yet, or we need to do some experimental things by sending the raw payload, we can use the following API to send raw request directly, which works for both single request and batch mode.

Single request mode:

```rust
use divoom::*;

let pixoo = PixooClient::new("192.168.0.123");
pixoo.send_raw_request("{ \"Command\": \"Device/SetHighLightMode\", \"Mode\": 0 }").await?.expect("Request should succeed.");
```

Batch mode:

```rust
use divoom::*;
let pixoo = PixooClient::new("192.168.0.123");
pixoo.start_batch()
.send_raw_request("{ \"Command\": \"Device/SetHighLightMode\", \"Mode\": 0 }".into())
.execute_with_raw_response().await.expect("Request should succeed.");
```

## Debugging

The debug logs are logged at debug level. Once we set the log level to debug, we will be able to start see it:
Expand Down
25 changes: 23 additions & 2 deletions divoom/src/clients/common/divoom_rest_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,32 @@ impl DivoomRestAPIClient {
Ok(response)
}

pub async fn send_raw_request_with_body(
&self,
url_path: &str,
body: String,
) -> DivoomAPIResult<String> {
let url = format!("{}{}", self.server_url_base, url_path);
debug!("Sending request: Url = \"{}\", Body = \"{}\"", url, body);

let request = self.http_client.post(url).body(body);
let response = self.send_raw_request_with_request_builder(request).await?;
Ok(response)
}

async fn send_request_with_request_builder<T: DeserializeOwned>(
&self,
request: RequestBuilder,
) -> DivoomAPIResult<T> {
let response_text = self.send_raw_request_with_request_builder(request).await?;
let parsed_response = serde_json::from_str::<T>(&response_text)?;
Ok(parsed_response)
}

async fn send_raw_request_with_request_builder(
&self,
request: RequestBuilder,
) -> DivoomAPIResult<String> {
let response = request.send().await?;
debug!(
"Response header received: StatusCode = {}",
Expand All @@ -60,7 +82,6 @@ impl DivoomRestAPIClient {
let response_text = response.text().await?;
debug!("Response received: Body = \"{}\"", response_text);

let parsed_response = serde_json::from_str(&response_text)?;
Ok(parsed_response)
Ok(response_text)
}
}
18 changes: 15 additions & 3 deletions divoom/src/clients/pixoo/pixoo_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ macro_rules! impl_pixoo_client_api {
pub async fn $api_name(&self) -> DivoomAPIResult<$resp_return_type> {
let response: $resp_type = PixooCommandBuilder::start(self.client.clone())
.$api_name()
.execute_raw::<$resp_type>()
.execute_with_parsed_response::<$resp_type>()
.await?;

let error_code = response.error_code();
Expand All @@ -50,7 +50,7 @@ macro_rules! impl_pixoo_client_api {
pub async fn $api_name(&self, $($api_arg: $api_arg_type),*) -> DivoomAPIResult<$resp_return_type> {
let response: $resp_type = PixooCommandBuilder::start(self.client.clone())
.$api_name($($api_arg),*)
.execute_raw::<$resp_type>()
.execute_with_parsed_response::<$resp_type>()
.await?;

let error_code = response.error_code();
Expand Down Expand Up @@ -305,7 +305,7 @@ impl PixooClient {
let response: DivoomPixooCommandBatchExecuteCommandsResponse =
PixooCommandBuilder::start_batch(self.client.clone())
.send_image_animation(animation)
.execute_raw::<DivoomPixooCommandBatchExecuteCommandsResponse>()
.execute_with_parsed_response::<DivoomPixooCommandBatchExecuteCommandsResponse>()
.await?;

let error_code = response.error_code();
Expand Down Expand Up @@ -362,6 +362,18 @@ impl PixooClient {
}
}

/// # Raw API implementation
impl PixooClient {
pub async fn send_raw_request(&self, request: String) -> DivoomAPIResult<String> {
let response: String = PixooCommandBuilder::start(self.client.clone())
.send_raw_request(request)
.execute_with_raw_response()
.await?;

Ok(response)
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
40 changes: 38 additions & 2 deletions divoom/src/clients/pixoo/pixoo_command_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ impl PixooCommandBuilder {
(self.client, command_count, request_body)
}

pub(crate) async fn execute_raw<TResp: DeserializeOwned>(self) -> DivoomAPIResult<TResp> {
pub(crate) async fn execute_with_parsed_response<TResp: DeserializeOwned>(
self,
) -> DivoomAPIResult<TResp> {
let (client, command_count, request_body) = self.build();
if command_count == 0 {
return Err(DivoomAPIError::ParameterError(
Expand All @@ -51,6 +53,19 @@ impl PixooCommandBuilder {
.await
}

pub async fn execute_with_raw_response(self) -> DivoomAPIResult<String> {
let (client, command_count, request_body) = self.build();
if command_count == 0 {
return Err(DivoomAPIError::ParameterError(
"No command is built yet!".to_string(),
));
}

client
.send_raw_request_with_body("/post", request_body)
.await
}

pub async fn execute(self) -> DivoomAPIResult<()> {
if self.command_store.mode() == PixooCommandStoreMode::Single {
return Err(DivoomAPIError::ParameterError(
Expand All @@ -60,7 +75,7 @@ impl PixooCommandBuilder {
}

let response = self
.execute_raw::<DivoomPixooCommandBatchExecuteCommandsResponse>()
.execute_with_parsed_response::<DivoomPixooCommandBatchExecuteCommandsResponse>()
.await?;
if response.error_code() != 0 {
return Err(DivoomAPIError::ServerError(
Expand Down Expand Up @@ -368,6 +383,14 @@ impl PixooCommandBuilder {
);
}

/// Raw API implementations
impl PixooCommandBuilder {
pub fn send_raw_request(mut self, request: String) -> PixooCommandBuilder {
self.command_store.append(request);
self
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -501,6 +524,19 @@ mod tests {
);
}

#[test]
fn pixoo_command_builder_should_work_with_raw_commands_in_batch_mode() {
let client = Rc::new(DivoomRestAPIClient::new("http://192.168.0.123".to_string()));
let builder = PixooCommandBuilder::start_batch(client)
.send_raw_request("{ \"Command\": \"Device/SetHighLightMode\", \"Mode\": 0 }".into());

run_pixoo_command_builder_test(
builder,
1,
"test_data/pixoo_command_builder_tests/raw_commands.json",
);
}

fn run_pixoo_command_builder_test(
builder: PixooCommandBuilder,
expected_command_count: usize,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Command": "Draw/CommandList",
"CommandList": [
{
"Command": "Device/SetHighLightMode",
"Mode": 0
}
]
}

0 comments on commit c5f7765

Please sign in to comment.