Skip to content

Commit

Permalink
docs(dvmql): add initial documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
sotirangelo committed Jan 14, 2024
1 parent f36d9c4 commit efccd0a
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 34 deletions.
48 changes: 28 additions & 20 deletions src/dvmql/datasources.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
use std::collections::HashMap;
//! # Datasources
//!
//! This module containts deserialization logic for the datasources XML file.

use anyhow::Result;
use serde::Deserialize;
use std::collections::HashMap;

use super::helpers::read_xml_file;

/// Helper function for loading and deserializing the datasources XML file
pub fn load_datasources_xml(datasources_path: String) -> Result<HashMap<String, Datasource>> {
let init_datasources: InitDatasources = read_xml_file(datasources_path)?;
let init_datasources: DeserializedDatasources = read_xml_file(datasources_path)?;
let res: HashMap<String, Datasource> = init_datasources
.datasource
.iter()
Expand All @@ -25,13 +29,15 @@ pub fn load_datasources_xml(datasources_path: String) -> Result<HashMap<String,
Ok(res)
}

/// Intermediate representation of the deserialized datasources XML file.
#[derive(Deserialize, Debug, PartialEq)]
struct InitDatasources {
datasource: Vec<InitDatasource>,
struct DeserializedDatasources {
datasource: Vec<DeserializedDatasource>,
}

/// Intermediate representation of a datasource in the deserialized datasources XML file.
#[derive(Deserialize, Debug, PartialEq)]
struct InitDatasource {
struct DeserializedDatasource {
#[serde(rename = "@type", default)]
ds_type: String,
id: u8,
Expand All @@ -48,8 +54,7 @@ struct InitDatasource {
database: Option<String>,
}

impl InitDatasource {}

/// Enum representing the different types of datasources.
#[derive(Debug, PartialEq)]
pub enum Datasource {
Csv(Csv),
Expand All @@ -58,6 +63,7 @@ pub enum Datasource {
Database(Database),
}

/// CSV datasource (Also used for XML for now)
#[derive(Debug, PartialEq)]
pub struct Csv {
id: u8,
Expand All @@ -68,8 +74,8 @@ pub struct Csv {
headings: String,
}

impl From<&InitDatasource> for Csv {
fn from(ds: &InitDatasource) -> Csv {
impl From<&DeserializedDatasource> for Csv {
fn from(ds: &DeserializedDatasource) -> Csv {
Csv {
id: ds.id,
name: ds.name.to_owned(),
Expand All @@ -93,6 +99,7 @@ impl From<&InitDatasource> for Csv {
}
}

/// Excel datasource
#[derive(Debug, PartialEq)]
pub struct Excel {
id: u8,
Expand All @@ -102,8 +109,8 @@ pub struct Excel {
sheet: String,
headings: String,
}
impl From<&InitDatasource> for Excel {
fn from(ds: &InitDatasource) -> Excel {
impl From<&DeserializedDatasource> for Excel {
fn from(ds: &DeserializedDatasource) -> Excel {
Excel {
id: ds.id,
name: ds.name.to_owned(),
Expand All @@ -127,6 +134,7 @@ impl From<&InitDatasource> for Excel {
}
}

/// Database datasource
#[derive(Debug, PartialEq)]
pub struct Database {
id: u8,
Expand All @@ -138,8 +146,8 @@ pub struct Database {
database: String,
}

impl From<&InitDatasource> for Database {
fn from(ds: &InitDatasource) -> Database {
impl From<&DeserializedDatasource> for Database {
fn from(ds: &DeserializedDatasource) -> Database {
Database {
id: ds.id,
name: ds.name.to_owned(),
Expand Down Expand Up @@ -173,10 +181,10 @@ mod tests {

use super::*;

fn get_init_datasources() -> InitDatasources {
InitDatasources {
fn get_init_datasources() -> DeserializedDatasources {
DeserializedDatasources {
datasource: vec![
InitDatasource {
DeserializedDatasource {
ds_type: String::from("csv"),
id: 1,
name: String::from("myCSV"),
Expand All @@ -191,7 +199,7 @@ mod tests {
password: None,
database: None,
},
InitDatasource {
DeserializedDatasource {
ds_type: String::from("excel"),
id: 2,
name: String::from("myExcel"),
Expand All @@ -206,7 +214,7 @@ mod tests {
password: None,
database: None,
},
InitDatasource {
DeserializedDatasource {
ds_type: String::from("xml"),
id: 3,
name: String::from("myCSV2"),
Expand All @@ -221,7 +229,7 @@ mod tests {
password: None,
database: None,
},
InitDatasource {
DeserializedDatasource {
ds_type: String::from("db"),
id: 4,
name: String::from("sqlDb"),
Expand Down Expand Up @@ -298,7 +306,7 @@ mod tests {
#[test]
fn test_loading_initial_datasource_structs() {
let path = get_test_file_path();
let datasources: InitDatasources = read_xml_file(path).unwrap();
let datasources: DeserializedDatasources = read_xml_file(path).unwrap();
assert_eq!(datasources, get_init_datasources());
}

Expand Down
4 changes: 2 additions & 2 deletions src/dvmql/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::{fs::File, io::BufReader};

use anyhow::{Context, Result};
use quick_xml::de::from_reader;
use serde::de::DeserializeOwned;
use std::{fs::File, io::BufReader};

/// Helper function for reading an XML file and deserializing it into a struct.
pub fn read_xml_file<T: DeserializeOwned>(xml_file_path: String) -> Result<T> {
let file = File::open(&xml_file_path)
.with_context(|| format!("Failed to open file: {}", &xml_file_path))?;
Expand Down
5 changes: 5 additions & 0 deletions src/dvmql/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
//! # DVMQL
//!
//! DVMQL is a query language for the DVM. It relies on XML files for
//! defining queries and the data sources to be queried.

pub mod datasources;
pub mod query;

Expand Down
25 changes: 16 additions & 9 deletions src/dvmql/query/deserialization.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
use std::str::FromStr;
//! # Query deserialization
//!
//! This module containts deserialization logic for the query XML file.

use anyhow::Result;

use serde::de::Deserializer;
use serde::Deserialize;
use std::str::FromStr;

use crate::dvmql::helpers::read_xml_file;
use crate::transform::aggregate::AggregationType;
use crate::transform::Transformation;

pub fn load_query_xml(query_path: String) -> Result<Query> {
let query: Query = read_xml_file(query_path)?;
Ok(query)
}

/// Intermediate representation of the deserialized query XML file.
///
/// This struct is used to deserialize the XML file into a more
/// usable format.
#[derive(Deserialize, Debug, PartialEq)]
pub struct Query {
#[serde(rename = "rootnode")]
Expand All @@ -22,6 +22,7 @@ pub struct Query {
pub nodes: Vec<DeserializedNode>,
}

/// Intermediate representation of a node in the deserialized query XML file.
#[derive(Deserialize, Debug, PartialEq)]
pub struct DeserializedNode {
#[serde(rename = "onnode")]
Expand All @@ -37,6 +38,7 @@ pub struct DeserializedNode {
pub output: bool,
}

/// Deserialization helper function for the theta
fn deserialize_theta<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
where
D: Deserializer<'de>,
Expand All @@ -48,6 +50,7 @@ where
Ok(Some(s))
}

/// Deserialization helper function for nodes' children
fn deserialize_children<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
where
D: Deserializer<'de>,
Expand All @@ -59,6 +62,7 @@ where
Ok(s.split(',').map(|part| part.trim().to_string()).collect())
}

/// Deserialization helper function for nodes' transformations
fn deserialize_transformations<'de, D>(deserializer: D) -> Result<Vec<Transformation>, D::Error>
where
D: Deserializer<'de>,
Expand Down Expand Up @@ -89,6 +93,7 @@ where
Ok(transformations)
}

/// Deserialization helper function for nodes' output
fn deserialize_output<'de, D>(deserializer: D) -> Result<bool, D::Error>
where
D: Deserializer<'de>,
Expand Down Expand Up @@ -145,12 +150,14 @@ mod tests {
}
}

use crate::dvmql::helpers::read_xml_file;

#[test]
fn test_load_query_xml() {
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
path.push("test_data/example_query.xml");
let path = path.to_str().unwrap().to_string();
let expected_query = get_expected_query();
assert_eq!(load_query_xml(path).unwrap(), expected_query)
assert_eq!(read_xml_file::<Query>(path).unwrap(), expected_query)
}
}
10 changes: 8 additions & 2 deletions src/dvmql/query/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
//! # Query
//!
//! This module containts deserialization logic for query XML files.

mod deserialization;
pub mod tree;

use anyhow::Result;

use self::tree::TreeNode;
use self::{deserialization::Query, tree::TreeNode};
use crate::dvmql::helpers::read_xml_file;

/// Helper function for loading a query XML file and building the tree structure.
pub fn load_query_xml(query_path: String) -> Result<TreeNode> {
let query = deserialization::load_query_xml(query_path)?;
let query: Query = read_xml_file(query_path)?;
let tree = tree::build_tree(query)?;
Ok(tree)
}
8 changes: 7 additions & 1 deletion src/dvmql/query/tree.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
//! # Tree structure produced by DVMQL query
//!
//! This module contains the logic for building the tree structure defined in a DVMQL query.

use anyhow::{Context, Result};
use std::collections::HashMap;

use crate::{dvmql::query::deserialization::DeserializedNode, transform::Transformation};

use super::deserialization::Query;

/// Node of the tree structure defined in a DVMQL query.
pub struct TreeNode {
pub name: String,
pub label: String,
Expand Down Expand Up @@ -34,6 +38,7 @@ impl TreeNode {
}
}

/// Helper function for taking a deserialized query and building the tree structure.
pub fn build_tree(query: Query) -> Result<TreeNode> {
let mut deserialized_nodes_map: HashMap<String, DeserializedNode> = query
.nodes
Expand All @@ -54,6 +59,7 @@ pub fn build_tree(query: Query) -> Result<TreeNode> {
Ok(root_node)
}

/// Helper function for building a node of the tree structure.
fn build_node(
node: DeserializedNode,
nodes_map: &mut HashMap<String, DeserializedNode>,
Expand Down

0 comments on commit efccd0a

Please sign in to comment.