Skip to content

Commit

Permalink
Merge pull request #1243 from rainlanguage/2025-02-06-yaml-parsing-er…
Browse files Browse the repository at this point in the history
…rors
  • Loading branch information
hardyjosh authored Feb 8, 2025
2 parents 3c6151c + f2d1563 commit 172a689
Show file tree
Hide file tree
Showing 13 changed files with 1,347 additions and 579 deletions.
86 changes: 62 additions & 24 deletions crates/settings/src/deployer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use strict_yaml_rust::StrictYaml;
use thiserror::Error;
use typeshare::typeshare;
use yaml::{
context::Context, default_document, optional_string, require_hash, require_string, YamlError,
YamlParsableHash,
context::Context, default_document, optional_string, require_hash, require_string,
FieldErrorKind, YamlError, YamlParsableHash,
};

#[cfg(target_family = "wasm")]
Expand Down Expand Up @@ -60,14 +60,19 @@ impl Deployer {
.or_else(|_| Ok(deployer_key.to_string()));
}
} else {
return Err(YamlError::ParseError(
"deployers field must be a map".to_string(),
));
return Err(YamlError::Field {
kind: FieldErrorKind::InvalidType {
field: "deployers".to_string(),
expected: "a map".to_string(),
},
location: "root".to_string(),
});
}
}
Err(YamlError::ParseError(format!(
"network key not found for deployer: {deployer_key}"
)))
Err(YamlError::Field {
kind: FieldErrorKind::Missing(format!("network for deployer '{}'", deployer_key)),
location: "root".to_string(),
})
}
}

Expand Down Expand Up @@ -131,32 +136,46 @@ impl YamlParsableHash for Deployer {
) -> Result<HashMap<String, Self>, YamlError> {
let mut deployers = HashMap::new();

let networks = Network::parse_all_from_yaml(documents.clone(), None)?;

for document in &documents {
let document_read = document.read().map_err(|_| YamlError::ReadLockError)?;

if let Ok(deployers_hash) = require_hash(&document_read, Some("deployers"), None) {
for (key_yaml, deployer_yaml) in deployers_hash {
let deployer_key = key_yaml.as_str().unwrap_or_default().to_string();

let address = Deployer::validate_address(&require_string(
deployer_yaml,
Some("address"),
Some(format!(
"address string missing in deployer: {deployer_key}"
)),
)?)?;
let location = format!("deployer '{}'", deployer_key);

let address_str =
require_string(deployer_yaml, Some("address"), Some(location.clone()))?;
let address =
Deployer::validate_address(&address_str).map_err(|e| YamlError::Field {
kind: FieldErrorKind::InvalidValue {
field: "address".to_string(),
reason: e.to_string(),
},
location: location.clone(),
})?;

let network_name = match optional_string(deployer_yaml, "network") {
Some(network_name) => network_name,
None => deployer_key.clone(),
};
let network = Network::parse_from_yaml(documents.clone(), &network_name, None)?;
let network = networks
.get(&network_name)
.ok_or_else(|| YamlError::Field {
kind: FieldErrorKind::InvalidValue {
field: "network".to_string(),
reason: format!("Network '{}' not found", network_name),
},
location: location.clone(),
})?;

let deployer = Deployer {
document: document.clone(),
key: deployer_key.clone(),
address,
network: Arc::new(network),
network: Arc::new(network.clone()),
};

if deployers.contains_key(&deployer_key) {
Expand All @@ -168,9 +187,10 @@ impl YamlParsableHash for Deployer {
}

if deployers.is_empty() {
return Err(YamlError::ParseError(
"missing field: deployers".to_string(),
));
return Err(YamlError::Field {
kind: FieldErrorKind::Missing("deployers".to_string()),
location: "root".to_string(),
});
}

Ok(deployers)
Expand Down Expand Up @@ -350,7 +370,13 @@ deployers: test
let error = Deployer::parse_network_key(vec![get_document(yaml)], "mainnet").unwrap_err();
assert_eq!(
error,
YamlError::ParseError("deployers field must be a map".to_string())
YamlError::Field {
kind: FieldErrorKind::InvalidType {
field: "deployers".to_string(),
expected: "a map".to_string(),
},
location: "root".to_string(),
}
);

let yaml = r#"
Expand All @@ -364,7 +390,13 @@ deployers:
let error = Deployer::parse_network_key(vec![get_document(yaml)], "mainnet").unwrap_err();
assert_eq!(
error,
YamlError::ParseError("deployers field must be a map".to_string())
YamlError::Field {
kind: FieldErrorKind::InvalidType {
field: "deployers".to_string(),
expected: "a map".to_string(),
},
location: "root".to_string(),
}
);

let yaml = r#"
Expand All @@ -378,7 +410,13 @@ deployers:
let error = Deployer::parse_network_key(vec![get_document(yaml)], "mainnet").unwrap_err();
assert_eq!(
error,
YamlError::ParseError("deployers field must be a map".to_string())
YamlError::Field {
kind: FieldErrorKind::InvalidType {
field: "deployers".to_string(),
expected: "a map".to_string(),
},
location: "root".to_string(),
}
);

let yaml = r#"
Expand Down
85 changes: 55 additions & 30 deletions crates/settings/src/deployment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use thiserror::Error;
use typeshare::typeshare;
use yaml::{
context::{Context, GuiContextTrait},
default_document, require_hash, require_string, YamlError, YamlParsableHash,
default_document, require_hash, require_string, FieldErrorKind, YamlError, YamlParsableHash,
};

#[cfg(target_family = "wasm")]
Expand Down Expand Up @@ -46,14 +46,19 @@ impl Deployment {
return require_string(deployment_yaml, Some("order"), None);
}
} else {
return Err(YamlError::ParseError(
"deployments field must be a map".to_string(),
));
return Err(YamlError::Field {
kind: FieldErrorKind::InvalidType {
field: "deployments".to_string(),
expected: "a map".to_string(),
},
location: "root".to_string(),
});
}
}
Err(YamlError::ParseError(format!(
"order key not found for deployment: {deployment_key}"
)))
Err(YamlError::Field {
kind: FieldErrorKind::Missing("order".to_string()),
location: format!("deployment '{deployment_key}'"),
})
}
}

Expand All @@ -70,6 +75,7 @@ impl YamlParsableHash for Deployment {
if let Ok(deployments_hash) = require_hash(&document_read, Some("deployments"), None) {
for (key_yaml, deployment_yaml) in deployments_hash {
let deployment_key = key_yaml.as_str().unwrap_or_default().to_string();
let location = format!("deployment '{deployment_key}'");

if let Some(context) = context {
if let Some(current_deployment) = context.get_current_deployment() {
Expand All @@ -81,28 +87,19 @@ impl YamlParsableHash for Deployment {

let mut context = Context::from_context(context);

let order_key = require_string(
deployment_yaml,
Some("order"),
Some(format!(
"order string missing in deployment: {deployment_key}"
)),
)?;
let order_key =
require_string(deployment_yaml, Some("order"), Some(location.clone()))?;
context.add_current_order(order_key.clone());

let order =
Order::parse_from_yaml(documents.clone(), &order_key, Some(&context))?;
context.add_order(Arc::new(order.clone()));

let scenario_key =
require_string(deployment_yaml, Some("scenario"), Some(location.clone()))?;
let scenario = Scenario::parse_from_yaml(
documents.clone(),
&require_string(
deployment_yaml,
Some("scenario"),
Some(format!(
"scenario string missing in deployment: {deployment_key}"
)),
)?,
&scenario_key,
Some(&context),
)?;

Expand Down Expand Up @@ -130,9 +127,10 @@ impl YamlParsableHash for Deployment {
}

if deployments.is_empty() {
return Err(YamlError::ParseError(
"missing field: deployments".to_string(),
));
return Err(YamlError::Field {
kind: FieldErrorKind::Missing("deployments".to_string()),
location: "root".to_string(),
});
}

Ok(deployments)
Expand Down Expand Up @@ -303,7 +301,10 @@ test: test
let error = Deployment::parse_all_from_yaml(vec![get_document(yaml)], None).unwrap_err();
assert_eq!(
error,
YamlError::ParseError("missing field: deployments".to_string())
YamlError::Field {
kind: FieldErrorKind::Missing("deployments".to_string()),
location: "root".to_string(),
}
);

let yaml = r#"
Expand Down Expand Up @@ -333,7 +334,10 @@ deployments:
let error = Deployment::parse_all_from_yaml(vec![get_document(yaml)], None).unwrap_err();
assert_eq!(
error,
YamlError::ParseError("order string missing in deployment: deployment1".to_string())
YamlError::Field {
kind: FieldErrorKind::Missing("order".to_string()),
location: "deployment 'deployment1'".to_string(),
}
);

let yaml = r#"
Expand Down Expand Up @@ -364,7 +368,10 @@ deployments:
let error = Deployment::parse_all_from_yaml(vec![get_document(yaml)], None).unwrap_err();
assert_eq!(
error,
YamlError::ParseError("scenario string missing in deployment: deployment1".to_string())
YamlError::Field {
kind: FieldErrorKind::Missing("scenario".to_string()),
location: "deployment 'deployment1'".to_string(),
}
);

let yaml = r#"
Expand Down Expand Up @@ -534,7 +541,13 @@ deployments: test
Deployment::parse_order_key(vec![get_document(yaml)], "deployment1").unwrap_err();
assert_eq!(
error,
YamlError::ParseError("deployments field must be a map".to_string())
YamlError::Field {
kind: FieldErrorKind::InvalidType {
field: "deployments".to_string(),
expected: "a map".to_string()
},
location: "root".to_string(),
}
);

let yaml = r#"
Expand All @@ -545,7 +558,13 @@ deployments:
Deployment::parse_order_key(vec![get_document(yaml)], "deployment1").unwrap_err();
assert_eq!(
error,
YamlError::ParseError("deployments field must be a map".to_string())
YamlError::Field {
kind: FieldErrorKind::InvalidType {
field: "deployments".to_string(),
expected: "a map".to_string()
},
location: "root".to_string(),
}
);

let yaml = r#"
Expand All @@ -556,7 +575,13 @@ deployments:
Deployment::parse_order_key(vec![get_document(yaml)], "deployment1").unwrap_err();
assert_eq!(
error,
YamlError::ParseError("deployments field must be a map".to_string())
YamlError::Field {
kind: FieldErrorKind::InvalidType {
field: "deployments".to_string(),
expected: "a map".to_string()
},
location: "root".to_string(),
}
);

let yaml = r#"
Expand Down
Loading

0 comments on commit 172a689

Please sign in to comment.