mdt_core 0.7.0

update markdown content anywhere using comments as template tags
Documentation
use miette::Diagnostic;
use thiserror::Error;

#[derive(Debug, Diagnostic, Error)]
#[non_exhaustive]
pub enum MdtError {
	#[error(transparent)]
	#[diagnostic(code(mdt::io_error))]
	Io(#[from] std::io::Error),

	#[error("failure to load markdown: {0}")]
	#[diagnostic(code(mdt::markdown))]
	Markdown(String),

	#[error("missing closing tag for block: `{0}`")]
	#[diagnostic(
		code(mdt::missing_closing_tag),
		help("add `<!-- {{/{0}}} -->` to close this block")
	)]
	MissingClosingTag(String),

	#[error("invalid token sequence")]
	#[diagnostic(code(mdt::invalid_token_sequence))]
	InvalidTokenSequence(usize),

	#[error("no provider found for consumer block: `{0}`")]
	#[diagnostic(
		code(mdt::missing_provider),
		help("define a provider block `<!-- {{@{0}}} -->...<!-- {{/{0}}} -->` in a *.t.md file")
	)]
	MissingProvider(String),

	#[error("consumer block `{name}` in {file} is out of date")]
	#[diagnostic(
		code(mdt::stale_consumer),
		help("run `mdt update` to synchronize consumer blocks")
	)]
	StaleConsumer { name: String, file: String },

	#[error("failed to parse config file: {0}")]
	#[diagnostic(
		code(mdt::config_parse),
		help("check that mdt.toml is valid TOML with [data] and/or [exclude] sections")
	)]
	ConfigParse(String),

	#[error("failed to load data file `{path}`: {reason}")]
	#[diagnostic(code(mdt::data_file))]
	DataFile { path: String, reason: String },

	#[error("failed to execute data script for `{namespace}`: {reason}")]
	#[diagnostic(code(mdt::data_script))]
	DataScript { namespace: String, reason: String },

	#[error("unsupported data file format: `{0}`")]
	#[diagnostic(
		code(mdt::unsupported_format),
		help("supported formats: text, json, toml, yaml, yml, kdl, ini")
	)]
	UnsupportedDataFormat(String),

	#[error("template rendering failed: {0}")]
	#[diagnostic(code(mdt::template_render))]
	TemplateRender(String),

	#[error("duplicate provider `{name}`: defined in `{first_file}` and `{second_file}`")]
	#[diagnostic(
		code(mdt::duplicate_provider),
		help("each provider block name must be unique across the project")
	)]
	DuplicateProvider {
		name: String,
		first_file: String,
		second_file: String,
	},

	#[error("unknown transformer: `{0}`")]
	#[diagnostic(
		code(mdt::unknown_transformer),
		help(
			"available transformers: trim, trimStart, trimEnd, indent, prefix, suffix, \
			 linePrefix, lineSuffix, wrap, codeBlock, code, replace, if"
		)
	)]
	UnknownTransformer(String),

	#[error("transformer `{name}` expects {expected} argument(s), got {got}")]
	#[diagnostic(code(mdt::invalid_transformer_args))]
	InvalidTransformerArgs {
		name: String,
		expected: String,
		got: usize,
	},

	#[error("file too large: `{path}` is {size} bytes (limit: {limit} bytes)")]
	#[diagnostic(
		code(mdt::file_too_large),
		help("increase the file size limit in mdt.toml or exclude this file")
	)]
	FileTooLarge { path: String, size: u64, limit: u64 },

	#[error("symlink cycle detected at: `{path}`")]
	#[diagnostic(
		code(mdt::symlink_cycle),
		help("remove the circular symlink or exclude this path")
	)]
	SymlinkCycle { path: String },

	#[error("unconvertible float value in data file `{path}`: {value}")]
	#[diagnostic(
		code(mdt::unconvertible_float),
		help("NaN and Infinity are not valid JSON numbers")
	)]
	UnconvertibleFloat { path: String, value: String },
}

pub type MdtResult<T> = Result<T, MdtError>;
pub type AnyError = Box<dyn std::error::Error>;
pub type AnyEmptyResult = Result<(), AnyError>;
pub type AnyResult<T> = Result<T, AnyError>;