// This file is part of Moonfire NVR, a security camera network video recorder. // Copyright (C) 2020 The Moonfire NVR Authors; see AUTHORS and LICENSE.txt. // SPDX-License-Identifier: GPL-v3.0-or-later WITH GPL-3.0-linking-exception. //! JSON/TOML-compatible serde types for use in the web API and `moonfire-nvr.toml`. use base::time::{Duration, Time}; use base::{err, Error}; use db::auth::SessionHash; use serde::ser::{Error as _, SerializeMap, SerializeSeq, Serializer}; use serde::{Deserialize, Deserializer, Serialize}; use std::ops::Not; use uuid::Uuid; #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct TopLevel<'a> { pub time_zone_name: &'a str, pub server_version: &'static str, // Use a custom serializer which presents the map's values as a sequence and includes the // "days" and "camera_configs" attributes or not, according to the respective bools. #[serde(serialize_with = "TopLevel::serialize_cameras")] pub cameras: (&'a db::LockedDatabase, bool, bool), pub permissions: Permissions, #[serde(skip_serializing_if = "Option::is_none")] pub user: Option, #[serde(serialize_with = "TopLevel::serialize_signals")] pub signals: (&'a db::LockedDatabase, bool), #[serde(serialize_with = "TopLevel::serialize_signal_types")] pub signal_types: &'a db::LockedDatabase, } #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct Session { #[serde(serialize_with = "Session::serialize_csrf")] pub csrf: SessionHash, } impl Session { fn serialize_csrf(csrf: &SessionHash, serializer: S) -> Result where S: Serializer, { let mut tmp = [0u8; 32]; csrf.encode_base64(&mut tmp); serializer.serialize_str(::std::str::from_utf8(&tmp[..]).expect("base64 is UTF-8")) } } /// JSON serialization wrapper for a single camera when processing `/api/` and /// `/api/cameras//`. See `ref/api.md` for details. #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct Camera<'a> { pub uuid: Uuid, pub id: i32, pub short_name: &'a str, #[serde(skip_serializing_if = "Option::is_none")] pub config: Option<&'a db::json::CameraConfig>, #[serde(serialize_with = "Camera::serialize_streams")] pub streams: [Option>; db::db::NUM_STREAM_TYPES], } #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct Stream<'a> { pub id: i32, pub retain_bytes: i64, pub min_start_time_90k: Option