implement basic macro string

This commit is contained in:
Moritz Hölting 2024-11-06 09:45:46 +00:00
parent 87a113aa9f
commit 84ee2a5295
3 changed files with 108 additions and 2 deletions

View File

@ -10,7 +10,7 @@ use chksum_md5 as md5;
use super::Function;
use crate::{
prelude::Datapack,
util::compile::{CompileOptions, FunctionCompilerState, MutCompilerState},
util::{compile::{CompileOptions, FunctionCompilerState, MutCompilerState}, MacroString},
};
/// Represents a command that can be included in a function.
@ -19,6 +19,8 @@ use crate::{
pub enum Command {
/// A command that is already formatted as a string.
Raw(String),
/// A command that contains macro usages
UsesMacro(MacroString),
/// Message to be printed only in debug mode
Debug(String),
/// Execute command
@ -45,6 +47,7 @@ impl Command {
) -> Vec<String> {
match self {
Self::Raw(command) => vec![command.clone()],
Self::UsesMacro(command) => vec![compile_macro(command)],
Self::Debug(message) => compile_debug(message, options),
Self::Execute(ex) => ex.compile(options, global_state, function_state),
Self::Group(commands) => compile_group(commands, options, global_state, function_state),
@ -59,7 +62,8 @@ impl Command {
// TODO: change comment to compile to `1`, make sure nothing breaks
Self::Comment(_) => 0,
Self::Debug(_) => usize::from(options.debug),
Self::Raw(cmd) => cmd.split('\n').count(),
Self::Raw(cmd) => cmd.lines().count(),
Self::UsesMacro(cmd) => cmd.line_count(),
Self::Execute(ex) => ex.get_count(options),
Self::Group(_) => 1,
}
@ -71,6 +75,7 @@ impl Command {
match self {
Self::Comment(_) | Self::Debug(_) | Self::Group(_) => true,
Self::Raw(cmd) => validate_raw_cmd(cmd, pack_formats),
Self::UsesMacro(cmd) => validate_raw_cmd(&cmd.compile(), pack_formats),
Self::Execute(ex) => ex.validate(pack_formats),
}
}
@ -103,6 +108,14 @@ fn compile_debug(message: &str, option: &CompileOptions) -> Vec<String> {
}
}
fn compile_macro(command: &MacroString) -> String {
if command.contains_macro() {
format!("${}", command.compile())
} else {
command.compile()
}
}
#[tracing::instrument(skip_all, fields(commands = ?commands))]
fn compile_group(
commands: &[Command],

89
src/util/macro_string.rs Normal file
View File

@ -0,0 +1,89 @@
#![allow(clippy::module_name_repetitions)]
use std::borrow::Cow;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum MacroString {
String(String),
MacroString(Vec<MacroStringPart>),
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum MacroStringPart {
String(String),
MacroUsage(String),
}
impl MacroString {
/// Returns whether the [`MacroString`] contains any macro usages
#[must_use]
pub fn contains_macro(&self) -> bool {
match self {
Self::String(_) => false,
Self::MacroString(parts) => !parts
.iter()
.all(|p| matches!(p, MacroStringPart::String(_))),
}
}
/// Compiles to a string that Minecraft can interpret
#[must_use]
pub fn compile(&self) -> String {
match self {
Self::String(s) => s.to_owned(),
Self::MacroString(parts) => parts
.iter()
.map(|p| match p {
MacroStringPart::String(s) => Cow::Borrowed(s),
MacroStringPart::MacroUsage(m) => Cow::Owned(format!("$({m})")),
})
.collect::<Vec<_>>()
.iter()
.map(|p| p.as_str())
.collect::<Vec<_>>()
.join(""),
}
}
/// Returns the amount of lines the string has
#[must_use]
pub fn line_count(&self) -> usize {
match self {
Self::String(s) => s.lines().count(),
Self::MacroString(parts) => {
parts
.iter()
.map(|p| match p {
MacroStringPart::String(s) => s.lines().count() - 1,
MacroStringPart::MacroUsage(_) => 0,
})
.sum::<usize>()
+ 1
}
}
}
}
impl From<String> for MacroString {
fn from(value: String) -> Self {
Self::String(value)
}
}
impl From<&str> for MacroString {
fn from(value: &str) -> Self {
Self::String(value.to_string())
}
}
impl From<String> for MacroStringPart {
fn from(value: String) -> Self {
Self::String(value)
}
}
impl From<&str> for MacroStringPart {
fn from(value: &str) -> Self {
Self::String(value.to_string())
}
}

View File

@ -2,7 +2,11 @@
pub mod compile;
mod extendable_queue;
mod macro_string;
pub(crate) mod pack_format;
#[doc(inline)]
pub use extendable_queue::ExtendableQueue;
#[doc(inline)]
pub use macro_string::{MacroString, MacroStringPart};