rustenium-bidi-definitions 0.1.1

Generated WebDriver BiDi protocol type definitions for Rustenium
Documentation
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

use serde::Deserializer;

use crate::{Command, Event};

fn float_or_int_to_u64<'de, D>(deserializer: D) -> Result<u64, D::Error>
where
    D: Deserializer<'de>,
{
    let value = serde_json::Value::deserialize(deserializer)?;

    match value {
        serde_json::Value::Number(num) => {
            if let Some(i) = num.as_u64() {
                Ok(i)
            } else if let Some(f) = num.as_f64() {
                Ok(f as u64)
            } else {
                Err(serde::de::Error::custom("Invalid number"))
            }
        }
        _ => Err(serde::de::Error::custom("Expected a number")),
    }
}

fn option_float_or_int_to_u64<'de, D>(deserializer: D) -> Result<Option<u64>, D::Error>
where
    D: Deserializer<'de>,
{
    let value = serde_json::Value::deserialize(deserializer)?;

    if value.is_null() {
        return Ok(None);
    }

    match value {
        serde_json::Value::Number(num) => {
            if let Some(i) = num.as_u64() {
                Ok(Some(i))
            } else if let Some(f) = num.as_f64() {
                Ok(Some(f as u64))
            } else {
                Err(serde::de::Error::custom("Invalid number"))
            }
        }
        _ => Err(serde::de::Error::custom("Expected a number")),
    }
}

fn deserialize_empty_map<'de, D>(deserializer: D) -> Result<Extensible, D::Error>
where
    D: serde::Deserializer<'de>,
{
    let map = Extensible::deserialize(deserializer)?;

    if map.is_empty() {
        Ok(map)
    } else {
        Err(serde::de::Error::custom("expected empty object"))
    }
}

pub type Extensible = HashMap<String, serde_json::Value>;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CommandMessage {
    #[serde(rename = "id")]
    pub id: u64,
    #[serde(flatten)]
    pub command_data: Command,
    #[serde(flatten)]
    pub extensible: Extensible,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EmptyParams {
    #[serde(flatten, deserialize_with = "deserialize_empty_map")]
    pub extensible: Extensible,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Message {
    ErrorResponse(ErrorResponse),
    CommandResponse(CommandResponse),
    Event(EventResponse),
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CommandResponse {
    #[serde(rename = "type")]
    pub r#type: SuccessEnum,
    #[serde(rename = "id")]
    #[serde(deserialize_with = "float_or_int_to_u64")]
    pub id: u64,
    #[serde(rename = "result")]
    pub result: serde_json::Value,
    #[serde(flatten)]
    pub extensible: Extensible,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ErrorResponse {
    #[serde(rename = "type")]
    pub r#type: ErrorEnum,
    #[serde(rename = "id")]
    #[serde(deserialize_with = "option_float_or_int_to_u64")]
    pub id: Option<u64>,
    #[serde(rename = "error")]
    pub error: ErrorCode,
    #[serde(rename = "message")]
    pub message: String,
    #[serde(rename = "stacktrace")]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub stacktrace: Option<String>,
    #[serde(flatten)]
    pub extensible: Extensible,
}

impl std::fmt::Display for ErrorResponse {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "Error[{}]: {} (ID: {}){}",
            self.error,
            self.message,
            self.id.map_or("None".to_string(), |id| id.to_string()),
            self.stacktrace
                .as_ref()
                .map_or("".to_string(), |st| format!("\nStacktrace:\n{}", st))
        )
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EventResponse {
    #[serde(rename = "type")]
    pub r#type: EventEnum,
    #[serde(flatten)]
    pub event_data: Event,
    #[serde(flatten)]
    pub extensible: Extensible,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ErrorCode {
    #[serde(rename = "invalid argument")]
    InvalidArgument,
    #[serde(rename = "invalid selector")]
    InvalidSelector,
    #[serde(rename = "invalid session id")]
    InvalidSessionId,
    #[serde(rename = "invalid web extension")]
    InvalidWebExtension,
    #[serde(rename = "move target out of bounds")]
    MoveTargetOutOfBounds,
    #[serde(rename = "no such alert")]
    NoSuchAlert,
    #[serde(rename = "no such network collector")]
    NoSuchNetworkCollector,
    #[serde(rename = "no such element")]
    NoSuchElement,
    #[serde(rename = "no such frame")]
    NoSuchFrame,
    #[serde(rename = "no such handle")]
    NoSuchHandle,
    #[serde(rename = "no such history entry")]
    NoSuchHistoryEntry,
    #[serde(rename = "no such intercept")]
    NoSuchIntercept,
    #[serde(rename = "no such network data")]
    NoSuchNetworkData,
    #[serde(rename = "no such node")]
    NoSuchNode,
    #[serde(rename = "no such request")]
    NoSuchRequest,
    #[serde(rename = "no such script")]
    NoSuchScript,
    #[serde(rename = "no such storage partition")]
    NoSuchStoragePartition,
    #[serde(rename = "no such user context")]
    NoSuchUserContext,
    #[serde(rename = "no such web extension")]
    NoSuchWebExtension,
    #[serde(rename = "session not created")]
    SessionNotCreated,
    #[serde(rename = "unable to capture screen")]
    UnableToCaptureScreen,
    #[serde(rename = "unable to close drivers")]
    UnableToCloseBrowser,
    #[serde(rename = "unable to set cookie")]
    UnableToSetCookie,
    #[serde(rename = "unable to set file input")]
    UnableToSetFileInput,
    #[serde(rename = "unavailable network data")]
    UnavailableNetworkData,
    #[serde(rename = "underspecified storage partition")]
    UnderspecifiedStoragePartition,
    #[serde(rename = "unknown command")]
    UnknownCommand,
    #[serde(rename = "unknown error")]
    UnknownError,
    #[serde(rename = "unsupported operation")]
    UnsupportedOperation,
}

impl std::fmt::Display for ErrorCode {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            ErrorCode::InvalidArgument => write!(f, "invalid argument"),
            ErrorCode::InvalidSelector => write!(f, "invalid selector"),
            ErrorCode::InvalidSessionId => write!(f, "invalid session id"),
            ErrorCode::InvalidWebExtension => write!(f, "invalid web extension"),
            ErrorCode::MoveTargetOutOfBounds => write!(f, "move target out of bounds"),
            ErrorCode::NoSuchAlert => write!(f, "no such alert"),
            ErrorCode::NoSuchNetworkCollector => write!(f, "no such network collector"),
            ErrorCode::NoSuchElement => write!(f, "no such element"),
            ErrorCode::NoSuchFrame => write!(f, "no such frame"),
            ErrorCode::NoSuchHandle => write!(f, "no such handle"),
            ErrorCode::NoSuchHistoryEntry => write!(f, "no such history entry"),
            ErrorCode::NoSuchIntercept => write!(f, "no such intercept"),
            ErrorCode::NoSuchNetworkData => write!(f, "no such network data"),
            ErrorCode::NoSuchNode => write!(f, "no such node"),
            ErrorCode::NoSuchRequest => write!(f, "no such request"),
            ErrorCode::NoSuchScript => write!(f, "no such script"),
            ErrorCode::NoSuchStoragePartition => write!(f, "no such storage partition"),
            ErrorCode::NoSuchUserContext => write!(f, "no such user context"),
            ErrorCode::NoSuchWebExtension => write!(f, "no such web extension"),
            ErrorCode::SessionNotCreated => write!(f, "session not created"),
            ErrorCode::UnableToCaptureScreen => write!(f, "unable to capture screen"),
            ErrorCode::UnableToCloseBrowser => write!(f, "unable to close drivers"),
            ErrorCode::UnableToSetCookie => write!(f, "unable to set cookie"),
            ErrorCode::UnableToSetFileInput => write!(f, "unable to set file input"),
            ErrorCode::UnavailableNetworkData => write!(f, "unavailable network data"),
            ErrorCode::UnderspecifiedStoragePartition => {
                write!(f, "underspecified storage partition")
            }
            ErrorCode::UnknownCommand => write!(f, "unknown command"),
            ErrorCode::UnknownError => write!(f, "unknown error"),
            ErrorCode::UnsupportedOperation => write!(f, "unsupported operation"),
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SuccessEnum {
    #[serde(rename = "success")]
    Success,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ErrorEnum {
    #[serde(rename = "error")]
    Error,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum EventEnum {
    #[serde(rename = "event")]
    Event,
}