algohub-server 0.1.18

Extremely fast async online judge backend based on Rust
Documentation
use serde::{Deserialize, Serialize};
use surrealdb::sql::Thing;

use super::UserRecordId;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Sample {
    pub input: String,
    pub output: String,
}

#[derive(Serialize, Deserialize, Clone)]
pub struct TestCase {
    pub input: Thing,
    pub output: Thing,
}

impl From<UserTestCase<'_>> for TestCase {
    fn from(value: UserTestCase<'_>) -> Self {
        TestCase {
            input: Thing::from(("asset", value.input)),
            output: Thing::from(("asset", value.output)),
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum ProblemVisibility {
    ContestOnly,
    Public,
    Private,
    Internal,
}

#[derive(Clone, Serialize, Deserialize)]
pub struct Problem {
    pub id: Option<Thing>,

    pub title: String,
    pub description: String,
    pub input: Option<String>,
    pub output: Option<String>,
    pub samples: Vec<Sample>,
    pub hint: Option<String>,

    pub time_limit: u64,
    pub memory_limit: u64,
    pub test_cases: Vec<TestCase>,

    pub creator: Thing,
    pub owner: Thing,
    pub categories: Vec<String>,
    pub tags: Vec<String>,

    pub visibility: ProblemVisibility,
    pub contest: Option<Thing>,

    pub created_at: chrono::NaiveDateTime,
    pub updated_at: chrono::NaiveDateTime,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserTestCase<'r> {
    pub input: &'r str,
    pub output: &'r str,
}

#[derive(Serialize, Deserialize)]
#[serde(crate = "rocket::serde")]
pub struct CreateProblem<'r> {
    pub id: &'r str,
    pub token: &'r str,

    pub title: &'r str,
    pub description: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub input: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub output: Option<String>,
    pub samples: Vec<Sample>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub hint: Option<String>,

    pub owner: UserRecordId,
    pub time_limit: u64,
    pub memory_limit: u64,
    pub test_cases: Vec<UserTestCase<'r>>,

    pub categories: Vec<String>,
    pub tags: Vec<String>,

    pub visibility: ProblemVisibility,
}

impl From<CreateProblem<'_>> for Problem {
    fn from(val: CreateProblem<'_>) -> Self {
        Problem {
            id: None,
            title: val.title.to_string(),
            description: val.description.to_string(),
            input: val.input,
            output: val.output,
            samples: val.samples,
            hint: val.hint,
            time_limit: val.time_limit,
            memory_limit: val.memory_limit,
            test_cases: val.test_cases.into_iter().map(Into::into).collect(),
            creator: ("account", val.id).into(),
            owner: val.owner.into(),
            categories: val.categories,
            tags: val.tags,
            visibility: val.visibility,
            contest: None,
            created_at: chrono::Local::now().naive_local(),
            updated_at: chrono::Local::now().naive_local(),
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OwnedUserTestCase {
    pub input: String,
    pub output: String,
}

impl From<TestCase> for OwnedUserTestCase {
    fn from(value: TestCase) -> Self {
        OwnedUserTestCase {
            input: value.input.id.to_string(),
            output: value.output.id.to_string(),
        }
    }
}

#[derive(Debug, Deserialize, Serialize)]
pub struct UserProblem {
    pub id: String,

    pub title: String,
    pub description: String,
    pub input: Option<String>,
    pub output: Option<String>,
    pub samples: Vec<Sample>,
    pub hint: Option<String>,

    pub time_limit: u64,
    pub memory_limit: u64,
    pub test_cases: Vec<OwnedUserTestCase>,

    pub creator: String,
    pub owner: UserRecordId,
    pub categories: Vec<String>,
    pub tags: Vec<String>,

    pub visibility: ProblemVisibility,

    pub created_at: chrono::NaiveDateTime,
    pub updated_at: chrono::NaiveDateTime,
}

impl From<Problem> for UserProblem {
    fn from(value: Problem) -> Self {
        UserProblem {
            id: value.id.unwrap().id.to_string(),
            title: value.title,
            description: value.description,
            input: value.input,
            output: value.output,
            samples: value.samples,
            hint: value.hint,
            time_limit: value.time_limit,
            memory_limit: value.memory_limit,
            test_cases: value.test_cases.into_iter().map(Into::into).collect(),
            creator: value.creator.id.to_string(),
            owner: value.owner.into(),
            categories: value.categories,
            tags: value.tags,
            visibility: value.visibility,
            created_at: value.created_at,
            updated_at: value.updated_at,
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServerTestCase {
    pub input: String,
    pub output: String,
}