-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
…nd-logic 🎨 separate python api and logic
- Loading branch information
Showing
6 changed files
with
228 additions
and
118 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
use crate::procedure::writer_schema::*; | ||
use std::collections::HashMap; | ||
|
||
#[derive(Debug, Clone)] | ||
enum Job { | ||
Resource(ResourceKind), | ||
Execution(Execution), | ||
Script(Text), | ||
} | ||
|
||
/// Internal builder to create a judge-procedure | ||
#[derive(Debug, Clone)] | ||
pub struct ProcedureBuilder { | ||
jobs: HashMap<String, Job>, | ||
} | ||
|
||
impl From<ProcedureBuilder> for Procedure { | ||
fn from(builder: ProcedureBuilder) -> Self { | ||
Self { | ||
resources: builder | ||
.jobs | ||
.iter() | ||
.filter_map(|(_, job)| match job { | ||
Job::Resource(resource) => Some(resource.clone()), | ||
_ => None, | ||
}) | ||
.collect(), | ||
executions: builder | ||
.jobs | ||
.iter() | ||
.filter_map(|(_, job)| match job { | ||
Job::Execution(execution) => Some(execution.clone()), | ||
_ => None, | ||
}) | ||
.collect(), | ||
scripts: builder | ||
.jobs | ||
.iter() | ||
.filter_map(|(_, job)| match job { | ||
Job::Script(script) => Some(script.clone()), | ||
_ => None, | ||
}) | ||
.collect(), | ||
} | ||
} | ||
} | ||
|
||
impl ProcedureBuilder { | ||
pub fn new() -> Self { | ||
ProcedureBuilder { | ||
jobs: HashMap::new(), | ||
} | ||
} | ||
|
||
/// Add a resource to the procedure and return the name of the resource | ||
pub fn add_resource(&mut self, resource: ResourceKind) -> Result<String, AddJobError> { | ||
let name = match &resource { | ||
ResourceKind::EmptyDirectory(empty_directory) => empty_directory.name.clone(), | ||
ResourceKind::RuntimeTextFile(runtime_text) => runtime_text.name.clone(), | ||
ResourceKind::TextFile(text) => text.name.clone(), | ||
}; | ||
self.jobs | ||
.insert(name.clone(), Job::Resource(resource)) | ||
.map_or_else( | ||
|| Ok(name.clone()), | ||
|_| Err(AddJobError::ResourceAlreadyExists(name.clone())), | ||
)?; | ||
Ok(name) | ||
} | ||
|
||
/// Add a script to the procedure and return the name of the script | ||
pub fn add_script(&mut self, script: Text) -> Result<String, AddJobError> { | ||
let name = script.name.clone(); | ||
self.jobs | ||
.insert(name.clone(), Job::Script(script)) | ||
.map_or_else( | ||
|| Ok(name.clone()), | ||
|_| Err(AddJobError::ResourceAlreadyExists(name.clone())), | ||
)?; | ||
Ok(name) | ||
} | ||
|
||
/// Add an execution to the procedure and return the name of the execution | ||
pub fn add_execution(&mut self, execution: Execution) -> Result<String, AddJobError> { | ||
let name = execution.name.clone(); | ||
// Check if all dependencies are present | ||
for dep in execution.depends_on.iter() { | ||
self.jobs | ||
.get(&dep.ref_to) | ||
.ok_or(AddJobError::DependencyNotFound(dep.ref_to.clone()))?; | ||
} | ||
self.jobs | ||
.get(&execution.script_name) | ||
.ok_or(AddJobError::DependencyNotFound( | ||
execution.script_name.clone(), | ||
))?; | ||
// Insert the execution | ||
let _ = self | ||
.jobs | ||
.insert(name.clone(), Job::Execution(execution)) | ||
.map_or_else( | ||
|| Ok(name.clone()), | ||
|_| Err(AddJobError::ResourceAlreadyExists(name.clone())), | ||
)?; | ||
Ok(name) | ||
} | ||
|
||
/// Export the procedure | ||
pub fn get_procedure(&self) -> Procedure { | ||
Procedure { | ||
resources: self | ||
.jobs | ||
.iter() | ||
.filter_map(|(_, job)| match job { | ||
Job::Resource(resource) => Some(resource.clone()), | ||
_ => None, | ||
}) | ||
.collect(), | ||
executions: self | ||
.jobs | ||
.iter() | ||
.filter_map(|(_, job)| match job { | ||
Job::Execution(execution) => Some(execution.clone()), | ||
_ => None, | ||
}) | ||
.collect(), | ||
scripts: self | ||
.jobs | ||
.iter() | ||
.filter_map(|(_, job)| match job { | ||
Job::Script(script) => Some(script.clone()), | ||
_ => None, | ||
}) | ||
.collect(), | ||
} | ||
} | ||
} | ||
|
||
#[derive(Clone, Debug, thiserror::Error)] | ||
pub enum AddJobError { | ||
#[error("Name {0} already exists")] | ||
ResourceAlreadyExists(String), | ||
#[error("Dependency {0} not found")] | ||
DependencyNotFound(String), | ||
} | ||
|
||
#[derive(Clone, Debug, thiserror::Error)] | ||
pub enum SchemaSerializationError { | ||
#[error("Failed to serialize schema: {0}")] | ||
SerializationError(String), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
use crate::models::*; | ||
use judge_core::procedure::writer_schema; | ||
use judge_core::procedure_builder; | ||
use pyo3::prelude::*; | ||
use pyo3_stub_gen::derive::*; | ||
use std::path::PathBuf; | ||
|
||
#[gen_stub_pyclass] | ||
#[pyclass] | ||
#[derive(Debug, Clone)] | ||
pub struct PyProcedureBuilder { | ||
builder: procedure_builder::ProcedureBuilder, | ||
} | ||
|
||
#[gen_stub_pymethods] | ||
#[pymethods] | ||
impl PyProcedureBuilder { | ||
#[new] | ||
fn new() -> Self { | ||
PyProcedureBuilder { | ||
builder: procedure_builder::ProcedureBuilder::new(), | ||
} | ||
} | ||
|
||
#[pyo3(name = "add_resource")] | ||
fn add_resource(&mut self, resource: resource_kind::PyResourceKind) -> output::PyOutput { | ||
let schema_resource = writer_schema::ResourceKind::from(resource); | ||
let name = self.builder.add_resource(schema_resource).unwrap(); | ||
let output = output::PyOutput::new(name); | ||
output | ||
} | ||
|
||
#[pyo3(name = "add_script")] | ||
fn add_script(&mut self, script: text::PyText) -> output::PyScriptOutput { | ||
let schema_script = writer_schema::Text::from(script); | ||
let name = self.builder.add_script(schema_script).unwrap(); | ||
let output = output::PyScriptOutput::new(name); | ||
output | ||
} | ||
|
||
#[pyo3(name = "add_execution")] | ||
fn add_execution(&mut self, execution: execution::PyExecution) -> output::PyOutput { | ||
let script_name = execution.script.name.clone(); | ||
let dependencies = execution | ||
.depends_on | ||
.iter() | ||
.map(|dep: &dependency::PyDependency| { | ||
let schema_dep = writer_schema::Dependency::from(dep.clone()); | ||
schema_dep | ||
}) | ||
.collect::<Vec<_>>(); | ||
let schema_execution = execution::new_execution(execution.name, script_name, dependencies); | ||
let name = self.builder.add_execution(schema_execution).unwrap(); | ||
let output = output::PyOutput::new(name); | ||
output | ||
} | ||
|
||
#[pyo3(name = "write_to")] | ||
fn write_to(&self, path: PathBuf) -> () { | ||
// output this instance as a json file | ||
let serializable = self.builder.get_procedure(); | ||
let json = serde_json::to_string(&serializable).unwrap(); | ||
std::fs::write(path, json).unwrap(); | ||
} | ||
} | ||
|
||
impl PyProcedureBuilder { | ||
pub fn get_schema_procedure(&self) -> writer_schema::Procedure { | ||
self.builder.get_procedure() | ||
} | ||
} |