boomack 0.4.1

Client library for Boomack
Documentation
//! Structures and functions to create
//! [`ClientRequest`](../api/struct.ClientRequest.html) instances
//! for making display requests

use std::path::PathBuf;
use super::json::*;
use super::api::*;
use string_join::Join;
use base64::prelude::*;

/// Display parameters contain all information
/// for a display request, except the actual content.
pub struct DisplayParameters<'l> {
    /// The target panel ID
    pub panel: Option<&'l str>,
    /// The target slot ID
    pub slot: Option<&'l str>,
    /// The media type of the content
    pub content_type: Option<&'l str>,
    /// The display request title
    pub title: Option<&'l str>,
    /// A vector with preset IDs
    pub presets: Vec<&'l str>,
    /// A JSON map with display options
    pub options: JsonMap,
}

fn init_display_request_body(p: &DisplayParameters) -> JsonMap {
    let mut req = JsonMap::new();
    if !p.presets.is_empty() {
        set_json_str_arr_value(&mut req, "presets", &p.presets);
    }
    if !p.options.is_empty() {
        set_json_obj_value(&mut req, "options", p.options.clone());
    }
    if let Some(panel_id) = p.panel {
        set_json_str_value(&mut req, "panel", panel_id);
    }
    if let Some(slot_id) = p.slot {
        set_json_str_value(&mut req, "slot", slot_id);
    }
    if let Some(content_type) = p.content_type {
        set_json_str_value(&mut req, "type", content_type);
    }
    if let Some(title) = p.title {
        set_json_str_value(&mut req, "title", title);
    }
    req
}

fn build_display_json_request(body: JsonMap) -> ClientRequest {
    let mut req = ClientRequest::post(String::from("display"));
    req.set_json_body(body);
    req
}

/// Create a display request with a string as `text` content.
pub fn display_text_request(p: &DisplayParameters, text: &str) -> ClientRequest {
    let mut body = init_display_request_body(p);
    set_json_str_value(&mut body, "text", text);
    build_display_json_request(body)
}

/// Create a display request with an URL as `src` content.
pub fn display_url_request(p: &DisplayParameters, url: &str) -> ClientRequest {
    let mut body = init_display_request_body(p);
    set_json_str_value(&mut body, "src", url);
    build_display_json_request(body)
}

fn build_stream_display_request_route(p: &DisplayParameters) -> String {
    let mut route = String::from("panels/");
    route.push_str(p.panel.unwrap_or("default"));
    if let Some(slot_id) = p.slot {
        route.push_str("/slots/");
        route.push_str(slot_id);
    }
    route.push_str("/display");
    route
}

fn build_stream_display_request(p: &DisplayParameters) -> ClientRequest {
    let route = build_stream_display_request_route(p);
    let mut req = ClientRequest::post(route);
    req.set_header("Content-Type", p.content_type.unwrap_or("application/octet-stream"));
    if !p.options.is_empty() {
        let json_options = serde_json::to_string(&p.options).unwrap();
        let b64_options = BASE64_STANDARD.encode(json_options);
        req.set_header("X-Boomack-Options", b64_options);
    }
    if !p.presets.is_empty() {
        let preset_list = ",".join(&p.presets);
        req.set_header("X-Boomack-Presets", preset_list);
    }
    if let Some(title) = p.title {
        req.set_header("X-Boomack-Title", urlencoding::encode(title));
    }
    req
}

/// Create a streaming display request with a file as content.
pub fn display_file_request(p: &DisplayParameters, filename: &str) -> ClientRequest {
    let mut req = build_stream_display_request(p);
    req.set_file_body(PathBuf::from(filename));
    req
}

/// Create a streaming display request with data from STDIN as content.
pub fn display_stdin_request(p: &DisplayParameters) -> ClientRequest {
    let mut req = build_stream_display_request(p);
    req.set_stdin_body();
    req
}