Skip to content

Commit

Permalink
Merge pull request #98 from niklasdewally/issue/86
Browse files Browse the repository at this point in the history
Better Error Handling
  • Loading branch information
ozgurakgun authored Nov 21, 2023
2 parents acdbcc1 + 983eaf0 commit eeca3bd
Show file tree
Hide file tree
Showing 12 changed files with 343 additions and 133 deletions.
143 changes: 139 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions conjure_oxide/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ serde_json = "1.0.108"
serde_with = "3.4.0"
thiserror = "1.0.50"
minion_rs = {path = "../solvers/minion" }
anyhow = "1.0.75"
clap = { version = "4.4.8", features = ["derive"] }
strum_macros = "0.25.3"
strum = "0.25.0"

[lints]
workspace = true
4 changes: 2 additions & 2 deletions conjure_oxide/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use walkdir::WalkDir;
fn main() -> io::Result<()> {
let out_dir = var("OUT_DIR").map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; // wrapping in a std::io::Error to match main's error type
let dest = Path::new(&out_dir).join("gen_tests.rs");
let mut f = File::create(&dest)?;
let mut f = File::create(dest)?;

let test_dir = "tests/integration";

Expand Down Expand Up @@ -45,7 +45,7 @@ fn write_test(file: &mut File, path: String, essence_files: Vec<String>) -> io::
file,
include_str!("./tests/gen_test_template"),
// TODO: better sanitisation of paths to function names
test_name = path.replace("./", "").replace("/", "_").replace("-", "_"),
test_name = path.replace("./", "").replace(['/', '-'], "_"),
test_dir = path,
essence_file = essence_files[0]
)
Expand Down
17 changes: 13 additions & 4 deletions conjure_oxide/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
//! Top-level error types for Conjure-Oxide.

use serde_json::Error as JsonError;
use thiserror::Error;

pub type Result<T> = std::result::Result<T, Error>;

#[derive(Debug, Error)]
pub enum Error {
#[error("JSON parsing error: {0}")]
JsonError(#[from] JsonError),
#[error("Error constructing model: {0}")]
ModelConstructError(String),
#[error("JSON error: {0}")]
JSON(#[from] JsonError),

#[error("Error parsing model: {0}")]
Parse(String),

#[error("{0} is not yet implemented.")]
NotImplemented(String),

#[error(transparent)]
Other(#[from] anyhow::Error),
}
100 changes: 46 additions & 54 deletions conjure_oxide/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,55 +1,47 @@
use std::collections::HashMap;

use conjure_oxide::ast::*;

fn main() {
// find a,b,c : int(1..3)
// such that a + b + c = 4
// such that a >= b

println!("Manual model:");

let a = Name::UserName(String::from("a"));
let b = Name::UserName(String::from("b"));
let c = Name::UserName(String::from("c"));

let mut variables = HashMap::new();
variables.insert(
a.clone(),
DecisionVariable {
domain: Domain::IntDomain(vec![Range::Bounded(1, 3)]),
},
);
variables.insert(
b.clone(),
DecisionVariable {
domain: Domain::IntDomain(vec![Range::Bounded(1, 3)]),
},
);
variables.insert(
c.clone(),
DecisionVariable {
domain: Domain::IntDomain(vec![Range::Bounded(1, 3)]),
},
);

let m = Model {
variables,
constraints: vec![
Expression::Eq(
Box::new(Expression::Sum(vec![
Expression::Reference(a.clone()),
Expression::Reference(b.clone()),
Expression::Reference(c.clone()),
])),
Box::new(Expression::ConstantInt(4)),
),
Expression::Geq(
Box::new(Expression::Reference(a.clone())),
Box::new(Expression::Reference(b.clone())),
),
],
};

println!("\n{:?}\n", m);
// (niklasdewally): temporary, gut this if you want!

use anyhow::{anyhow, bail};
use std::path::PathBuf;

use anyhow::Result as AnyhowResult;
use clap::{arg, command, Parser};
use conjure_oxide::parse::parse_json;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
#[arg(long, value_name = "SOLVER")]
solver: Option<String>,

#[arg(value_name = "INPUT_ESSENCE")]
input_file: PathBuf,
}

pub fn main() -> AnyhowResult<()> {
let cli = Cli::parse();
println!("Input file: {}", cli.input_file.display());
let input_file: &str = cli.input_file.to_str().ok_or(anyhow!(
"Given input_file could not be converted to a string"
))?;

/******************************************************/
/* Parse essence to json using Conjure */
/******************************************************/

let mut cmd = std::process::Command::new("conjure");
let output = cmd
.arg("pretty")
.arg("--output-format=astjson")
.arg(input_file)
.output()?;

let conjure_stderr = String::from_utf8(output.stderr)?;
if !conjure_stderr.is_empty() {
bail!(conjure_stderr);
}

let astjson = String::from_utf8(output.stdout)?;

let model = parse_json(&astjson)?;
println!("{:?}", model);
Ok(())
}
Loading

0 comments on commit eeca3bd

Please sign in to comment.