Skip to content

Commit

Permalink
Merge pull request #1079 from rainlanguage/2024-12-13-ob-yaml-subgraphs
Browse files Browse the repository at this point in the history
Implementing subgraphs in OrderbookYaml
  • Loading branch information
hardyjosh authored Dec 16, 2024
2 parents 6944bd9 + 197300e commit 75ff680
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 27 deletions.
1 change: 1 addition & 0 deletions crates/settings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub mod orderbook;
pub mod plot_source;
pub mod remote;
pub mod scenario;
pub mod subgraph;
pub mod token;
pub mod unit_test;
pub mod yaml;
Expand Down
7 changes: 1 addition & 6 deletions crates/settings/src/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ impl NetworkConfigSource {
#[cfg(test)]
mod tests {
use super::*;
use strict_yaml_rust::StrictYamlLoader;
use crate::yaml::tests::get_document;
use url::Url;

#[test]
Expand All @@ -217,11 +217,6 @@ mod tests {
assert_eq!(network.key, "local");
}

fn get_document(yaml: &str) -> Arc<RwLock<StrictYaml>> {
let document = StrictYamlLoader::load_from_str(yaml).unwrap()[0].clone();
Arc::new(RwLock::new(document))
}

#[test]
fn test_parse_networks_from_yaml() {
let yaml = r#"
Expand Down
82 changes: 82 additions & 0 deletions crates/settings/src/subgraph.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use crate::config::Subgraph;
use crate::yaml::{require_hash, require_string, YamlError, YamlParsableHash};
use std::{
collections::HashMap,
sync::{Arc, RwLock},
};
use strict_yaml_rust::StrictYaml;
use url::Url;

impl YamlParsableHash for Subgraph {
fn parse_all_from_yaml(
document: Arc<RwLock<StrictYaml>>,
) -> Result<HashMap<String, Url>, YamlError> {
let document_read = document.read().map_err(|_| YamlError::ReadLockError)?;
let subgraphs_hash = require_hash(
&document_read,
Some("subgraphs"),
Some("missing field: subgraphs".to_string()),
)?;

subgraphs_hash
.iter()
.map(|(key_yaml, subgraph_yaml)| {
let subgraph_key = key_yaml.as_str().unwrap_or_default().to_string();

let url = Url::parse(&require_string(
subgraph_yaml,
None,
Some(format!(
"subgraph value must be a string for key: {subgraph_key}"
)),
)?)?;

Ok((subgraph_key, url))
})
.collect()
}
}

#[cfg(test)]
mod test {
use super::*;
use crate::yaml::tests::get_document;

#[test]
fn test_parse_subgraphs_from_yaml() {
let yaml = r#"
test: test
"#;
let error = Subgraph::parse_all_from_yaml(get_document(yaml)).unwrap_err();
assert_eq!(
error,
YamlError::ParseError("missing field: subgraphs".to_string())
);

let yaml = r#"
subgraphs:
TestSubgraph:
test: https://subgraph.com
"#;
let error = Subgraph::parse_all_from_yaml(get_document(yaml)).unwrap_err();
assert_eq!(
error,
YamlError::ParseError(
"subgraph value must be a string for key: TestSubgraph".to_string()
)
);

let yaml = r#"
subgraphs:
TestSubgraph:
- https://subgraph.com
"#;
let error = Subgraph::parse_all_from_yaml(get_document(yaml)).unwrap_err();
assert_eq!(
error,
YamlError::ParseError(
"subgraph value must be a string for key: TestSubgraph".to_string()
)
);
}
}
9 changes: 2 additions & 7 deletions crates/settings/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ impl YamlParsableHash for Token {

let network = Network::parse_from_yaml(
document.clone(),
require_string(
&require_string(
token_yaml,
Some("network"),
Some(format!("network string missing in token: {token_key}")),
Expand Down Expand Up @@ -195,7 +195,7 @@ mod tests {
use self::test::*;
use super::*;
use alloy::primitives::Address;
use strict_yaml_rust::StrictYamlLoader;
use yaml::tests::get_document;

fn setup_networks() -> HashMap<String, Arc<Network>> {
let network = mock_network();
Expand All @@ -204,11 +204,6 @@ mod tests {
networks
}

fn get_document(yaml: &str) -> Arc<RwLock<StrictYaml>> {
let document = StrictYamlLoader::load_from_str(yaml).unwrap()[0].clone();
Arc::new(RwLock::new(document))
}

#[test]
fn test_token_creation_success_with_all_fields() {
let networks = setup_networks();
Expand Down
19 changes: 16 additions & 3 deletions crates/settings/src/yaml/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@ use strict_yaml_rust::{
EmitError, ScanError, StrictYaml, StrictYamlLoader,
};
use thiserror::Error;
use url::ParseError as UrlParseError;

pub trait YamlParsableHash: Sized + Clone {
fn parse_all_from_yaml(
document: Arc<RwLock<StrictYaml>>,
) -> Result<HashMap<String, Self>, YamlError>;

fn parse_from_yaml(document: Arc<RwLock<StrictYaml>>, key: String) -> Result<Self, YamlError> {
fn parse_from_yaml(document: Arc<RwLock<StrictYaml>>, key: &str) -> Result<Self, YamlError> {
let all = Self::parse_all_from_yaml(document)?;
all.get(&key)
.ok_or_else(|| YamlError::KeyNotFound(key))
all.get(key)
.ok_or_else(|| YamlError::KeyNotFound(key.to_string()))
.cloned()
}
}
Expand All @@ -41,6 +42,8 @@ pub enum YamlError {
RwLockReadGuardError(#[from] PoisonError<RwLockReadGuard<'static, StrictYaml>>),
#[error(transparent)]
RwLockWriteGuardError(#[from] PoisonError<RwLockWriteGuard<'static, StrictYaml>>),
#[error(transparent)]
UrlParseError(#[from] UrlParseError),
#[error("Yaml file is empty")]
EmptyFile,
#[error("Yaml parse error: {0}")]
Expand Down Expand Up @@ -154,3 +157,13 @@ pub fn require_vec<'a>(
pub fn optional_vec<'a>(value: &'a StrictYaml, field: &str) -> Option<&'a Array> {
value[field].as_vec()
}

#[cfg(test)]
pub mod tests {
use super::*;

pub fn get_document(yaml: &str) -> Arc<RwLock<StrictYaml>> {
let document = StrictYamlLoader::load_from_str(yaml).unwrap()[0].clone();
Arc::new(RwLock::new(document))
}
}
39 changes: 28 additions & 11 deletions crates/settings/src/yaml/orderbook.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::*;
use crate::{Network, Token};
use crate::{Network, Subgraph, Token};
use std::sync::{Arc, RwLock};
use strict_yaml_rust::StrictYamlEmitter;

Expand Down Expand Up @@ -36,23 +36,23 @@ impl OrderbookYaml {
Ok(networks.keys().cloned().collect())
}
pub fn get_network(&self, key: &str) -> Result<Network, YamlError> {
let networks = Network::parse_all_from_yaml(self.document.clone())?;
let network = networks
.get(key)
.ok_or(YamlError::KeyNotFound(key.to_string()))?;
Ok(network.clone())
Network::parse_from_yaml(self.document.clone(), key)
}

pub fn get_token_keys(&self) -> Result<Vec<String>, YamlError> {
let tokens = Token::parse_all_from_yaml(self.document.clone())?;
Ok(tokens.keys().cloned().collect())
}
pub fn get_token(&self, key: &str) -> Result<Token, YamlError> {
let tokens = Token::parse_all_from_yaml(self.document.clone())?;
let token = tokens
.get(key)
.ok_or(YamlError::KeyNotFound(key.to_string()))?;
Ok(token.clone())
Token::parse_from_yaml(self.document.clone(), key)
}

pub fn get_subgraph_keys(&self) -> Result<Vec<String>, YamlError> {
let subgraphs = Subgraph::parse_all_from_yaml(self.document.clone())?;
Ok(subgraphs.keys().cloned().collect())
}
pub fn get_subgraph(&self, key: &str) -> Result<Subgraph, YamlError> {
Subgraph::parse_from_yaml(self.document.clone(), key)
}
}

Expand Down Expand Up @@ -139,6 +139,23 @@ mod tests {
assert_eq!(network.network_id, Some(1));
assert_eq!(network.currency, Some("ETH".to_string()));

assert_eq!(ob_yaml.get_token_keys().unwrap().len(), 1);
let token = ob_yaml.get_token("token1").unwrap();
assert_eq!(
token.address,
Address::from_str("0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266").unwrap()
);
assert_eq!(token.decimals, Some(18));
assert_eq!(token.label, Some("Wrapped Ether".to_string()));
assert_eq!(token.symbol, Some("WETH".to_string()));

assert_eq!(ob_yaml.get_subgraph_keys().unwrap().len(), 2);
let subgraph = ob_yaml.get_subgraph("mainnet").unwrap();
assert_eq!(
subgraph,
Url::parse("https://api.thegraph.com/subgraphs/name/xyz").unwrap()
);

assert!(OrderbookYaml::new(YAML_WITHOUT_OPTIONAL_FIELDS.to_string(), true).is_ok());
}

Expand Down

0 comments on commit 75ff680

Please sign in to comment.