lib-humus-configuration 0.2.0

Helper crate for reading configuration files into data structures using serde.
Documentation
// SPDX-FileCopyrightText: 2025 Slatian
//
// SPDX-License-Identifier: LGPL-3.0-or-later

use crate::ConfigFormat;
use crate::Settings;
use crate::read_from_file;
#[cfg(feature = "json")]
use crate::read_from_json_file;
#[cfg(feature = "json5")]
use crate::read_from_json5_file;
#[cfg(feature = "toml")]
use crate::read_from_toml_file;
use serde::Deserialize;

#[derive(Debug, Deserialize, PartialEq, Eq)]
struct TestData {
	text: String,
	n: i64,
}

impl Default for TestData {
	fn default() -> Self {
		Self {
			text: "Foo Bar".to_string(),
			n: 123,
		}
	}
}

#[cfg(feature = "json")]
#[test]
fn test_reading_json() {
	// Test happy path
	let test_data: TestData = read_from_json_file("test-data/test.json").unwrap();
	assert_eq!(test_data, TestData::default());

	// Happy path with auto detection
	let (test_data, format): (TestData, ConfigFormat) =
		read_from_file("test-data/test.json", Settings::prefer_json()).unwrap();
	assert_eq!(test_data, TestData::default());
	assert_eq!(format, ConfigFormat::Json);
}

#[cfg(all(feature = "json", feature = "toml"))]
#[test]
fn test_reading_json_preferred_format_mismatch() {
	let (test_data, format): (TestData, ConfigFormat) =
		read_from_file("test-data/test.json", Settings::prefer_toml()).unwrap();
	assert_eq!(test_data, TestData::default());
	assert_eq!(format, ConfigFormat::Json);
}

#[cfg(all(feature = "json", feature = "json5"))]
#[test]
fn test_reading_json_format_mismatch() {
	// Test format mismatch
	let test_err = read_from_json_file::<TestData>("test-data/test.json5")
		.expect_err("Parsing JSON5 as JSON should fail");
	assert!(
		matches!(
			test_err.cause,
			crate::ErrorCause::FormatNotAllowed {
				format: ConfigFormat::Json5,
				prefer: ConfigFormat::Json
			}
		),
		"Expected a format not allowed error with the format set to Json5 and prefer set to Json, got: {test_err:?}"
	);
}

#[cfg(feature = "json5")]
#[test]
fn test_reading_json5() {
	// Test happy path
	let test_data: TestData = read_from_json5_file("test-data/test.json5").unwrap();
	assert_eq!(test_data, TestData::default());
	let test_data: TestData = read_from_json5_file("test-data/test.json").unwrap();
	assert_eq!(test_data, TestData::default());

	// Happy path with auto detection
	let (test_data, format): (TestData, ConfigFormat) =
		read_from_file("test-data/test.json5", Settings::prefer_json5()).unwrap();
	assert_eq!(test_data, TestData::default());
	assert_eq!(format, ConfigFormat::Json5);
}

#[cfg(all(feature = "json5", feature = "toml"))]
#[test]
fn test_reading_json5_preferred_format_mismatch() {
	let (test_data, format): (TestData, ConfigFormat) =
		read_from_file("test-data/test.json5", Settings::prefer_toml()).unwrap();
	assert_eq!(test_data, TestData::default());
	assert_eq!(format, ConfigFormat::Json5);
}

#[cfg(all(feature = "json5", feature = "toml"))]
#[test]
fn test_reading_json5_format_mismatch() {
	// Test format mismatch
	let test_err = read_from_json5_file::<TestData>("test-data/test.toml")
		.expect_err("Parsing TOML as JSON5 should fail");
	assert!(
		matches!(
			test_err.cause,
			crate::ErrorCause::FormatNotAllowed {
				format: ConfigFormat::Toml,
				prefer: ConfigFormat::Json5
			}
		),
		"Expected a format not allowed error with the format set to Json5 and prefer set to Json, got: {test_err:?}"
	);
}

#[cfg(feature = "toml")]
#[test]
fn test_reading_toml() {
	// Test happy path
	let test_data: TestData = read_from_toml_file("test-data/test.toml").unwrap();
	assert_eq!(test_data, TestData::default());

	// Happy path with auto detection
	let (test_data, format): (TestData, ConfigFormat) =
		read_from_file("test-data/test.toml", Settings::prefer_toml()).unwrap();
	assert_eq!(test_data, TestData::default());
	assert_eq!(format, ConfigFormat::Toml);
}

#[cfg(all(feature = "toml", feature = "json"))]
#[test]
fn test_reading_tom_preferred_format_mismatch() {
	let (test_data, format): (TestData, ConfigFormat) =
		read_from_file("test-data/test.toml", Settings::prefer_json()).unwrap();
	assert_eq!(test_data, TestData::default());
	assert_eq!(format, ConfigFormat::Toml);
}

#[cfg(all(feature = "toml", feature = "json"))]
#[test]
fn test_reading_toml_format_mismatch() {
	// Test format mismatch
	let test_err = read_from_toml_file::<TestData>("test-data/test.json")
		.expect_err("Parsing JSON as TOML should fail");
	assert!(
		matches!(
			test_err.cause,
			crate::ErrorCause::FormatNotAllowed {
				format: ConfigFormat::Json,
				prefer: ConfigFormat::Toml
			}
		),
		"Expected a format not allowed error with the format set to Json5 and prefer set to Json, got: {test_err:?}"
	);
}