odata_client_codegen 0.1.0

Strongly-typed OData client code generation
Documentation
use bumpalo::Bump;
use std::path::PathBuf;

use super::generate_client_module;
use crate::{
    entity_model::construct::{construct_entity_model, ConstructConfig},
    entity_model_filter::EntityModelFilter,
    input_file_test::{run_file_parse_test_single, run_file_parse_tests, InputFileTest},
    run_rustfmt, ItemNameWhitelist,
};

#[derive(Clone)]
struct TestCodegen {
    entity_set_whitelist: Option<ItemNameWhitelist<'static>>,
}

impl Default for TestCodegen {
    fn default() -> Self {
        TestCodegen {
            entity_set_whitelist: None,
        }
    }
}

const SERVICE_URL: &str = "http://services.odata.org/V4/TripPinService";

impl InputFileTest for TestCodegen {
    type Parsed = String;
    type ParseError = anyhow::Error;

    const INPUT_FILE_EXT: &'static str = ".xml";
    const OUTPUT_FILE_EXT: &'static str = ".rs";

    /// Generates the module token stream for an entity model document. `rustfmt` is run to check
    /// for syntax errors, and to ease human-verification when writing new results.
    fn parse_input_file(&mut self, file_contents: &str) -> Result<Self::Parsed, Self::ParseError> {
        let t_edmx = serde_xml_rs::from_str(file_contents)?;

        let arena = Bump::new();
        let config = ConstructConfig::default();
        let entity_model = construct_entity_model(t_edmx, SERVICE_URL.to_owned(), &arena, config)?;

        let stream = generate_client_module(
            &entity_model,
            &arena,
            self.entity_set_whitelist
                .as_mut()
                .map(|f| f as &mut dyn EntityModelFilter),
        );

        run_rustfmt(&stream.to_string())
    }

    fn write_test_result(&mut self, result: Self::Parsed) -> String {
        result
    }
}

#[test]
fn codegen_type_definitions() {
    let edmx_filepath: PathBuf = ["src", "codegen", "test", "type_definitions"]
        .iter()
        .collect();

    run_file_parse_tests(TestCodegen::default(), &edmx_filepath);
}

#[test]
fn codegen_namespaces() {
    let edmx_filepath: PathBuf = ["src", "codegen", "test", "namespaces"].iter().collect();

    run_file_parse_tests(TestCodegen::default(), &edmx_filepath);
}

#[test]
fn codegen_entity_container() {
    let edmx_filepath: PathBuf = ["src", "codegen", "test", "entity_container"]
        .iter()
        .collect();

    run_file_parse_tests(TestCodegen::default(), &edmx_filepath);
}

#[test]
fn codegen_filter_people_entity_set_only() {
    let edmx_filepath: PathBuf = ["src", "codegen", "test", "filter_entity_set_people.xml"]
        .iter()
        .collect();

    run_file_parse_test_single(
        TestCodegen {
            entity_set_whitelist: Some(dbg!(
                ItemNameWhitelist::new().with_entity_sets(vec!["People"])
            )),
        },
        edmx_filepath,
    );
}