wards 0.1.10

Библиотека для камеры Beward B2530RZQ-LP
Documentation
use std::collections::HashMap;

use base64::{prelude::BASE64_STANDARD, Engine};

use crate::{
    errors::WardError,
    http::{self, Response},
};

pub struct Camera {
    pub ip: String,
    pub port: u16,
    pub username: String,
    pub password: String,
    pub description: String,
    pub alarm_out: u8,
}

pub trait CameraFeatures {
    /// Создает объект Camera.
    ///
    /// По умолчанию задается 80 порт.
    /// Alart out по умолчанию 1.
    fn new(
        ip: String,
        port: Option<u16>,
        username: String,
        password: String,
        description: String,
        alarm_out: Option<u8>,
    ) -> Self;

    /// Отправляет запрос и возвращает тело ответа.
    ///
    /// Путь должен начанаться с "/".
    ///
    /// # Examples
    ///
    /// ```rust
    /// camera.send_request("/")
    /// ```
    fn send_request(&self, path: &str) -> Result<Response, WardError>;
}

impl CameraFeatures for Camera {
    fn new(
        ip: String,
        port: Option<u16>,
        username: String,
        password: String,
        description: String,
        alrm_out: Option<u8>,
    ) -> Self {
        Camera {
            ip,
            port: port.unwrap_or(80),
            username,
            password,
            description,
            alarm_out: alrm_out.unwrap_or(1),
        }
    }

    fn send_request(&self, path: &str) -> Result<Response, WardError> {
        let host = format!("{}:{}", &self.ip, &self.port);
        let path = format!("/cgi-bin{}", path.replace(" ", "%20"));

        let auth = BASE64_STANDARD.encode(format!("{}:{}", &self.username, &self.password));

        let mut headers = HashMap::new();
        headers.insert("Host", &self.ip);

        let header = format!(
            "GET {path} HTTP/1.1\n{}\nAuthorization: Basic {auth}\n\n",
            headers
                .iter()
                .map(|(i, x)| format!("{}: {}", i, x))
                .collect::<Vec<_>>()
                .join("\n")
        );

        let raw_response = http::send_request(&host, header.as_bytes())?;
        let response = http::Response::from_str(&raw_response).unwrap();

        Ok(response)
    }
}