1use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
7use thiserror::Error;
8
9#[derive(Debug, Error)]
11pub enum JsChallengeError {
12 #[error("Parse error: {0}")]
13 Parse(String),
14 #[error("Preprocess error: {0}")]
15 Preprocess(String),
16 #[error("Runtime error: {0}")]
17 Runtime(String),
18 #[error("IO error: {0}")]
19 Io(#[from] std::io::Error),
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
24#[serde(rename_all = "lowercase")]
25pub enum JsChallengeType {
26 N,
27 Sig,
28}
29
30impl JsChallengeType {
31 pub const fn as_str(&self) -> &'static str {
33 match self {
34 Self::N => "n",
35 Self::Sig => "sig",
36 }
37 }
38}
39
40#[derive(Debug, Clone, Serialize, Deserialize)]
42pub struct JsChallengeRequest {
43 #[serde(rename = "type")]
44 pub challenge_type: JsChallengeType,
45 pub challenges: Vec<String>,
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize)]
50#[serde(tag = "type", rename_all = "lowercase")]
51pub enum JsChallengeResponse {
52 Result { data: HashMap<String, String> },
53 Error { error: String },
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize)]
58#[serde(tag = "type", rename_all = "lowercase")]
59pub enum JsChallengeInput {
60 Player {
61 player: String,
62 requests: Vec<JsChallengeRequest>,
63 output_preprocessed: bool,
64 },
65 Preprocessed {
66 preprocessed_player: String,
67 requests: Vec<JsChallengeRequest>,
68 },
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
73#[serde(tag = "type", rename_all = "lowercase")]
74pub enum JsChallengeOutput {
75 Result {
76 #[serde(skip_serializing_if = "Option::is_none")]
77 preprocessed_player: Option<String>,
78 responses: Vec<JsChallengeResponse>,
79 },
80 Error {
81 error: String,
82 },
83}