implement basic macro string
This commit is contained in:
parent
87a113aa9f
commit
84ee2a5295
|
@ -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],
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
|
@ -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};
|
||||
|
|
Loading…
Reference in New Issue