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 serde::{Deserialize, Serialize};

use crate::ConfigFormat;

/// Which formats are allowed and which to prefer
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct Settings {
	/// The preferred configuration format. This is always allowed implicitly.
	pub prefer: ConfigFormat,

	/// Explicit permission to parse as JSON
	#[cfg(feature = "json")]
	pub allow_json: bool,

	/// Explicit permission to parse as JSON5.
	///
	/// Implicitly allows JSON as it is a subset of JSON5.
	#[cfg(feature = "json5")]
	pub allow_json5: bool,

	/// Explicit permission to parse as TOML
	#[cfg(feature = "toml")]
	pub allow_toml: bool,
}

impl Settings {
	/// Creates a new settings instance that allows all formats
	/// but prefers the given one.
	pub const fn allow_all(prefer: ConfigFormat) -> Self {
		Self {
			prefer,
			#[cfg(feature = "json")]
			allow_json: true,
			#[cfg(feature = "json5")]
			allow_json5: true,
			#[cfg(feature = "toml")]
			allow_toml: true,
		}
	}

	/// Allow all formats, but  prefer JSON.
	#[cfg(feature = "json")]
	pub const fn prefer_json() -> Self {
		Self::allow_all(ConfigFormat::Json)
	}

	/// Allow all formats, but prefer JSON5.
	#[cfg(feature = "json5")]
	pub const fn prefer_json5() -> Self {
		Self::allow_all(ConfigFormat::Json5)
	}

	/// Allow all formats, but prefer TOML.
	#[cfg(feature = "toml")]
	pub const fn prefer_toml() -> Self {
		Self::allow_all(ConfigFormat::Toml)
	}

	/// Creates a new settings instance that only allows the given preferred format.
	pub const fn allow_only(prefer: ConfigFormat) -> Self {
		Self {
			prefer,
			#[cfg(feature = "json")]
			allow_json: false,
			#[cfg(feature = "json5")]
			allow_json5: false,
			#[cfg(feature = "toml")]
			allow_toml: false,
		}
	}

	/// Only allows parsing as JSON.
	#[cfg(feature = "json")]
	pub const fn only_json() -> Self {
		Self::allow_only(ConfigFormat::Json)
	}

	/// Only allows parsing as JSON5 (and JSON).
	#[cfg(feature = "json5")]
	pub const fn only_json5() -> Self {
		Self::allow_only(ConfigFormat::Json5)
	}

	/// Only allow parsing as TOML.
	#[cfg(feature = "toml")]
	pub const fn only_toml() -> Self {
		Self::allow_only(ConfigFormat::Toml)
	}

	/// Wheter the settings allow the parsing the given configuration format.
	pub fn is_allowed(&self, test_for: ConfigFormat) -> bool {
		if test_for == self.prefer {
			return true;
		}
		match test_for {
			#[cfg(feature = "json")]
			ConfigFormat::Json => {
				#[cfg(not(feature = "json5"))]
				{
					self.allow_json
				}
				#[cfg(feature = "json5")]
				{
					self.allow_json
						|| self.allow_json5
						|| matches!(self.prefer, ConfigFormat::Json5)
				}
			}
			#[cfg(feature = "json5")]
			ConfigFormat::Json5 => self.allow_json5,
			#[cfg(feature = "toml")]
			ConfigFormat::Toml => self.allow_toml,
		}
	}
}