Compare commits
2 Commits
863bc784cc
...
7290806a2b
Author | SHA1 | Date |
---|---|---|
|
7290806a2b | |
|
e4c06e56ee |
|
@ -349,7 +349,7 @@ pub struct LuaCode {
|
|||
left_parenthesis: Punctuation,
|
||||
/// The arguments of the lua code.
|
||||
#[get = "pub"]
|
||||
variables: Option<ConnectedList<Identifier, Punctuation>>,
|
||||
inputs: Option<ConnectedList<Identifier, Punctuation>>,
|
||||
/// The right parenthesis of the lua code.
|
||||
#[get = "pub"]
|
||||
right_parenthesis: Punctuation,
|
||||
|
@ -550,10 +550,7 @@ impl<'a> Parser<'a> {
|
|||
Delimiter::Parenthesis,
|
||||
',',
|
||||
|parser| match parser.next_significant_token() {
|
||||
Reading::Atomic(Token::Identifier(identifier)) => {
|
||||
parser.forward();
|
||||
Ok(identifier)
|
||||
}
|
||||
Reading::Atomic(Token::Identifier(identifier)) => Ok(identifier),
|
||||
unexpected => {
|
||||
let err = Error::UnexpectedSyntax(UnexpectedSyntax {
|
||||
expected: syntax::error::SyntaxKind::Identifier,
|
||||
|
@ -597,7 +594,7 @@ impl<'a> Parser<'a> {
|
|||
Ok(Primary::Lua(Box::new(LuaCode {
|
||||
lua_keyword,
|
||||
left_parenthesis: variables.open,
|
||||
variables: variables.list,
|
||||
inputs: variables.list,
|
||||
right_parenthesis: variables.close,
|
||||
left_brace: tree.open,
|
||||
code: tree.tree?,
|
||||
|
|
|
@ -1,57 +1,50 @@
|
|||
//! Conversion functions for converting between tokens/ast-nodes and [`shulkerbox`] types
|
||||
|
||||
use shulkerbox::util::{MacroString, MacroStringPart};
|
||||
use shulkerbox::util::{MacroString as ExtMacroString, MacroStringPart as ExtMacroStringPart};
|
||||
|
||||
use crate::{
|
||||
lexical::token::{MacroStringLiteral, MacroStringLiteralPart},
|
||||
syntax::syntax_tree::AnyStringLiteral,
|
||||
};
|
||||
use crate::{lexical::token::MacroStringLiteral, syntax::syntax_tree::AnyStringLiteral};
|
||||
|
||||
impl From<&AnyStringLiteral> for MacroString {
|
||||
fn from(value: &AnyStringLiteral) -> Self {
|
||||
use super::util::{MacroString, MacroStringPart};
|
||||
|
||||
impl From<MacroString> for ExtMacroString {
|
||||
fn from(value: MacroString) -> Self {
|
||||
match value {
|
||||
AnyStringLiteral::StringLiteral(literal) => Self::from(literal.str_content().as_ref()),
|
||||
AnyStringLiteral::MacroStringLiteral(literal) => Self::from(literal),
|
||||
MacroString::String(s) => Self::String(s),
|
||||
MacroString::MacroString(parts) => {
|
||||
Self::MacroString(parts.into_iter().map(ExtMacroStringPart::from).collect())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AnyStringLiteral> for MacroString {
|
||||
impl From<MacroStringPart> for ExtMacroStringPart {
|
||||
fn from(value: MacroStringPart) -> Self {
|
||||
match value {
|
||||
MacroStringPart::String(s) => Self::String(s),
|
||||
MacroStringPart::MacroUsage(m) => Self::MacroUsage(m),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&AnyStringLiteral> for ExtMacroString {
|
||||
fn from(value: &AnyStringLiteral) -> Self {
|
||||
Self::from(MacroString::from(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AnyStringLiteral> for ExtMacroString {
|
||||
fn from(value: AnyStringLiteral) -> Self {
|
||||
Self::from(&value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&MacroStringLiteral> for MacroString {
|
||||
impl From<&MacroStringLiteral> for ExtMacroString {
|
||||
fn from(value: &MacroStringLiteral) -> Self {
|
||||
if value
|
||||
.parts()
|
||||
.iter()
|
||||
.any(|p| matches!(p, MacroStringLiteralPart::MacroUsage { .. }))
|
||||
{
|
||||
Self::MacroString(
|
||||
value
|
||||
.parts()
|
||||
.iter()
|
||||
.map(|part| match part {
|
||||
MacroStringLiteralPart::Text(span) => MacroStringPart::String(
|
||||
crate::util::unescape_macro_string(span.str()).to_string(),
|
||||
),
|
||||
MacroStringLiteralPart::MacroUsage { identifier, .. } => {
|
||||
MacroStringPart::MacroUsage(
|
||||
crate::util::identifier_to_macro(identifier.span.str()).to_string(),
|
||||
)
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
} else {
|
||||
Self::String(value.str_content())
|
||||
}
|
||||
Self::from(MacroString::from(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MacroStringLiteral> for MacroString {
|
||||
impl From<MacroStringLiteral> for ExtMacroString {
|
||||
fn from(value: MacroStringLiteral) -> Self {
|
||||
Self::from(&value)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::{fmt::Display, sync::Arc};
|
||||
|
||||
use super::{Scope, VariableData};
|
||||
use super::{util::MacroString, Scope, VariableData};
|
||||
use crate::{
|
||||
base::{self, Handler, VoidHandler},
|
||||
lexical::token::MacroStringLiteralPart,
|
||||
|
@ -15,10 +15,7 @@ use crate::{
|
|||
use enum_as_inner::EnumAsInner;
|
||||
|
||||
#[cfg(feature = "shulkerbox")]
|
||||
use shulkerbox::{
|
||||
prelude::{Command, Condition, Execute},
|
||||
util::MacroString,
|
||||
};
|
||||
use shulkerbox::prelude::{Command, Condition, Execute};
|
||||
|
||||
#[cfg(feature = "shulkerbox")]
|
||||
use super::{
|
||||
|
@ -51,7 +48,7 @@ impl Display for ComptimeValue {
|
|||
Self::Boolean(boolean) => write!(f, "{boolean}"),
|
||||
Self::Integer(int) => write!(f, "{int}"),
|
||||
Self::String(string) => write!(f, "{string}"),
|
||||
Self::MacroString(macro_string) => write!(f, "{}", macro_string.compile()),
|
||||
Self::MacroString(macro_string) => write!(f, "{macro_string}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -296,7 +293,7 @@ impl Primary {
|
|||
Self::Lua(lua) => {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "lua")] {
|
||||
lua.eval(&VoidHandler).map_or(false, |value| match value {
|
||||
lua.eval(scope, &VoidHandler).map_or(false, |(value, _)| match value {
|
||||
mlua::Value::Boolean(_) => matches!(r#type, ValueType::Boolean),
|
||||
mlua::Value::Integer(_) => matches!(r#type, ValueType::Integer),
|
||||
mlua::Value::String(_) => matches!(r#type, ValueType::String),
|
||||
|
@ -345,7 +342,7 @@ impl Primary {
|
|||
})
|
||||
}
|
||||
Self::Lua(lua) => lua
|
||||
.eval_comptime(&VoidHandler)
|
||||
.eval_comptime(scope, &VoidHandler)
|
||||
.inspect_err(|err| {
|
||||
handler.receive(err.clone());
|
||||
})
|
||||
|
@ -621,7 +618,7 @@ impl Transpiler {
|
|||
Primary::Lua(lua) =>
|
||||
{
|
||||
#[expect(clippy::option_if_let_else)]
|
||||
if let Some(value) = lua.eval_comptime(handler)? {
|
||||
if let Some(value) = lua.eval_comptime(scope, handler)? {
|
||||
self.store_comptime_value(&value, target, lua, handler)
|
||||
} else {
|
||||
let err = TranspileError::MissingValue(MissingValue {
|
||||
|
@ -1033,14 +1030,14 @@ impl Transpiler {
|
|||
Err(err)
|
||||
}
|
||||
},
|
||||
Primary::Lua(lua) => match lua.eval_comptime(handler)? {
|
||||
Primary::Lua(lua) => match lua.eval_comptime(scope, handler)? {
|
||||
Some(ComptimeValue::String(value)) => Ok((
|
||||
Vec::new(),
|
||||
ExtendedCondition::Runtime(Condition::Atom(value.into())),
|
||||
)),
|
||||
Some(ComptimeValue::MacroString(value)) => Ok((
|
||||
Vec::new(),
|
||||
ExtendedCondition::Runtime(Condition::Atom(value)),
|
||||
ExtendedCondition::Runtime(Condition::Atom(value.into())),
|
||||
)),
|
||||
Some(ComptimeValue::Boolean(boolean)) => {
|
||||
Ok((Vec::new(), ExtendedCondition::Comptime(boolean)))
|
||||
|
@ -1397,7 +1394,7 @@ impl Transpiler {
|
|||
..
|
||||
}
|
||||
| DataLocation::Tag { .. } => self.store_condition_success(
|
||||
ExtendedCondition::Runtime(Condition::Atom(value.clone())),
|
||||
ExtendedCondition::Runtime(Condition::Atom(value.clone().into())),
|
||||
target,
|
||||
source,
|
||||
handler,
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#[cfg(feature = "lua")]
|
||||
mod enabled {
|
||||
use std::sync::Arc;
|
||||
|
||||
use mlua::{Lua, Value};
|
||||
|
||||
use crate::{
|
||||
|
@ -10,6 +12,7 @@ mod enabled {
|
|||
transpile::{
|
||||
error::{LuaRuntimeError, TranspileError, TranspileResult},
|
||||
expression::ComptimeValue,
|
||||
Scope, VariableData,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -19,7 +22,11 @@ mod enabled {
|
|||
/// # Errors
|
||||
/// - If evaluation fails
|
||||
#[tracing::instrument(level = "debug", name = "eval_lua", skip_all, ret)]
|
||||
pub fn eval(&self, handler: &impl Handler<base::Error>) -> TranspileResult<mlua::Value> {
|
||||
pub fn eval(
|
||||
&self,
|
||||
scope: &Arc<Scope>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> TranspileResult<(mlua::Value, mlua::Lua)> {
|
||||
tracing::debug!("Evaluating Lua code");
|
||||
|
||||
let lua = Lua::new();
|
||||
|
@ -46,9 +53,17 @@ mod enabled {
|
|||
)
|
||||
};
|
||||
|
||||
self.add_globals(&lua).unwrap();
|
||||
if let Err(err) = self.add_globals(&lua, scope) {
|
||||
let err = TranspileError::LuaRuntimeError(LuaRuntimeError::from_lua_err(
|
||||
&err,
|
||||
self.span(),
|
||||
));
|
||||
handler.receive(crate::Error::from(err.clone()));
|
||||
return Err(err);
|
||||
}
|
||||
|
||||
lua.load(self.code())
|
||||
let res = lua
|
||||
.load(self.code())
|
||||
.set_name(name)
|
||||
.eval::<Value>()
|
||||
.map_err(|err| {
|
||||
|
@ -56,6 +71,11 @@ mod enabled {
|
|||
TranspileError::from(LuaRuntimeError::from_lua_err(&err, self.span()));
|
||||
handler.receive(crate::Error::from(err.clone()));
|
||||
err
|
||||
});
|
||||
|
||||
res.map(|v| {
|
||||
tracing::debug!("Lua code evaluated successfully");
|
||||
(v, lua)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -66,17 +86,16 @@ mod enabled {
|
|||
#[tracing::instrument(level = "debug", name = "eval_lua", skip_all, ret)]
|
||||
pub fn eval_comptime(
|
||||
&self,
|
||||
scope: &Arc<Scope>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> TranspileResult<Option<ComptimeValue>> {
|
||||
let lua_result = self.eval(handler)?;
|
||||
// required to keep the lua instance alive
|
||||
let (lua_result, _lua) = self.eval(scope, handler)?;
|
||||
|
||||
self.handle_lua_result(lua_result, handler)
|
||||
.inspect_err(|err| {
|
||||
handler.receive(err.clone());
|
||||
})
|
||||
}
|
||||
|
||||
fn add_globals(&self, lua: &Lua) -> mlua::Result<()> {
|
||||
fn add_globals(&self, lua: &Lua, scope: &Arc<Scope>) -> mlua::Result<()> {
|
||||
let globals = lua.globals();
|
||||
|
||||
let location = {
|
||||
|
@ -86,6 +105,32 @@ mod enabled {
|
|||
};
|
||||
globals.set("shu_location", location.to_string_lossy())?;
|
||||
|
||||
if let Some(inputs) = self.inputs() {
|
||||
for x in inputs.elements() {
|
||||
let name = x.span.str();
|
||||
let value = match scope.get_variable(name).as_deref() {
|
||||
Some(VariableData::MacroParameter { macro_name, .. }) => {
|
||||
Value::String(lua.create_string(format!("$({macro_name})"))?)
|
||||
}
|
||||
Some(VariableData::ScoreboardValue { objective, target }) => {
|
||||
let table = lua.create_table()?;
|
||||
table.set("objective", lua.create_string(objective)?)?;
|
||||
table.set("target", lua.create_string(target)?)?;
|
||||
Value::Table(table)
|
||||
}
|
||||
Some(VariableData::BooleanStorage { storage_name, path }) => {
|
||||
let table = lua.create_table()?;
|
||||
table.set("storage", lua.create_string(storage_name)?)?;
|
||||
table.set("path", lua.create_string(path)?)?;
|
||||
Value::Table(table)
|
||||
}
|
||||
Some(_) => todo!("allow other types"),
|
||||
None => todo!("throw correct error"),
|
||||
};
|
||||
globals.set(name, value)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -130,13 +175,15 @@ mod enabled {
|
|||
|
||||
#[cfg(not(feature = "lua"))]
|
||||
mod disabled {
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
base::{self, Handler},
|
||||
syntax::syntax_tree::expression::LuaCode,
|
||||
transpile::error::{TranspileError, TranspileResult},
|
||||
};
|
||||
|
||||
use crate::transpile::expression::ComptimeValue;
|
||||
use crate::transpile::{expression::ComptimeValue, Scope};
|
||||
|
||||
impl LuaCode {
|
||||
/// Will always return an error because Lua code evaluation is disabled.
|
||||
|
@ -145,7 +192,12 @@ mod disabled {
|
|||
/// # Errors
|
||||
/// - Always, as the lua feature is disabled
|
||||
#[tracing::instrument(level = "debug", name = "eval_lua", skip_all, ret)]
|
||||
pub fn eval(&self, handler: &impl Handler<base::Error>) -> TranspileResult<()> {
|
||||
pub fn eval(
|
||||
&self,
|
||||
scope: &Arc<Scope>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> TranspileResult<()> {
|
||||
let _ = scope;
|
||||
handler.receive(TranspileError::LuaDisabled);
|
||||
tracing::error!("Lua code evaluation is disabled");
|
||||
Err(TranspileError::LuaDisabled)
|
||||
|
@ -158,8 +210,10 @@ mod disabled {
|
|||
/// - If Lua code evaluation is disabled.
|
||||
pub fn eval_comptime(
|
||||
&self,
|
||||
scope: &Arc<Scope>,
|
||||
handler: &impl Handler<base::Error>,
|
||||
) -> TranspileResult<Option<ComptimeValue>> {
|
||||
let _ = scope;
|
||||
handler.receive(TranspileError::LuaDisabled);
|
||||
tracing::error!("Lua code evaluation is disabled");
|
||||
Err(TranspileError::LuaDisabled)
|
||||
|
|
|
@ -8,10 +8,7 @@ use std::{
|
|||
sync::{Arc, OnceLock},
|
||||
};
|
||||
|
||||
use shulkerbox::{
|
||||
datapack::{self, Command, Datapack, Execute},
|
||||
util::{MacroString, MacroStringPart},
|
||||
};
|
||||
use shulkerbox::datapack::{self, Command, Datapack, Execute};
|
||||
|
||||
use crate::{
|
||||
base::{
|
||||
|
@ -30,7 +27,10 @@ use crate::{
|
|||
},
|
||||
AnnotationAssignment,
|
||||
},
|
||||
transpile::error::{IllegalAnnotationContent, MissingFunctionDeclaration},
|
||||
transpile::{
|
||||
error::{IllegalAnnotationContent, MissingFunctionDeclaration},
|
||||
util::{MacroString, MacroStringPart},
|
||||
},
|
||||
};
|
||||
|
||||
use super::{
|
||||
|
@ -439,7 +439,7 @@ impl Transpiler {
|
|||
for expression in arguments.iter().flat_map(|x| x.iter()) {
|
||||
let value = match expression {
|
||||
Expression::Primary(Primary::Lua(lua)) => {
|
||||
lua.eval_comptime(handler).and_then(|val| match val {
|
||||
lua.eval_comptime(scope, handler).and_then(|val| match val {
|
||||
Some(ComptimeValue::MacroString(s)) => Ok(Parameter::Static(s)),
|
||||
Some(val) => Ok(Parameter::Static(val.to_string().into())),
|
||||
None => {
|
||||
|
@ -604,16 +604,17 @@ impl Transpiler {
|
|||
MacroString::String(s) => Command::Raw(format!(
|
||||
r#"data merge storage shulkerscript:function_arguments {{{s}}}"#
|
||||
)),
|
||||
MacroString::MacroString(_) => {
|
||||
Command::UsesMacro(super::util::join_macro_strings([
|
||||
MacroString::MacroString(_) => Command::UsesMacro(
|
||||
super::util::join_macro_strings([
|
||||
MacroString::String(
|
||||
"data merge storage shulkerscript:function_arguments {"
|
||||
.to_string(),
|
||||
),
|
||||
joined_statics,
|
||||
MacroString::String("}".to_string()),
|
||||
]))
|
||||
}
|
||||
])
|
||||
.into(),
|
||||
),
|
||||
};
|
||||
setup_cmds.push(statics_cmd);
|
||||
setup_cmds.extend(move_cmds);
|
||||
|
@ -782,9 +783,9 @@ impl Transpiler {
|
|||
Expression::Primary(Primary::MacroStringLiteral(string)) => {
|
||||
Ok(vec![Command::UsesMacro(string.into())])
|
||||
}
|
||||
Expression::Primary(Primary::Lua(code)) => match code.eval_comptime(handler)? {
|
||||
Expression::Primary(Primary::Lua(code)) => match code.eval_comptime(scope, handler)? {
|
||||
Some(ComptimeValue::String(cmd)) => Ok(vec![Command::Raw(cmd)]),
|
||||
Some(ComptimeValue::MacroString(cmd)) => Ok(vec![Command::UsesMacro(cmd)]),
|
||||
Some(ComptimeValue::MacroString(cmd)) => Ok(vec![Command::UsesMacro(cmd.into())]),
|
||||
Some(ComptimeValue::Boolean(_) | ComptimeValue::Integer(_)) => {
|
||||
let err = TranspileError::MismatchedTypes(MismatchedTypes {
|
||||
expected_type: ExpectedType::String,
|
||||
|
@ -805,7 +806,7 @@ impl Transpiler {
|
|||
),
|
||||
Expression::Binary(bin) => match bin.comptime_eval(scope, handler) {
|
||||
Some(ComptimeValue::String(cmd)) => Ok(vec![Command::Raw(cmd)]),
|
||||
Some(ComptimeValue::MacroString(cmd)) => Ok(vec![Command::UsesMacro(cmd)]),
|
||||
Some(ComptimeValue::MacroString(cmd)) => Ok(vec![Command::UsesMacro(cmd.into())]),
|
||||
_ => {
|
||||
let err = TranspileError::MismatchedTypes(MismatchedTypes {
|
||||
expression: bin.span(),
|
||||
|
@ -870,7 +871,7 @@ impl Transpiler {
|
|||
function_call.push_str(" {");
|
||||
parts.insert(0, MacroStringPart::String(function_call));
|
||||
parts.push(MacroStringPart::String('}'.to_string()));
|
||||
Command::UsesMacro(MacroString::MacroString(parts))
|
||||
Command::UsesMacro(MacroString::MacroString(parts).into())
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,48 @@
|
|||
//! Utility methods for transpiling
|
||||
|
||||
use shulkerbox::util::{MacroString, MacroStringPart};
|
||||
use std::fmt::Display;
|
||||
|
||||
use crate::{
|
||||
lexical::token::{MacroStringLiteral, MacroStringLiteralPart},
|
||||
syntax::syntax_tree::AnyStringLiteral,
|
||||
};
|
||||
|
||||
/// String that can contain macros
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum MacroString {
|
||||
/// A normal string
|
||||
String(String),
|
||||
/// A string containing macros
|
||||
MacroString(Vec<MacroStringPart>),
|
||||
}
|
||||
|
||||
/// Part of a [`MacroString`]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum MacroStringPart {
|
||||
/// A normal string
|
||||
String(String),
|
||||
/// A macro usage
|
||||
MacroUsage(String),
|
||||
}
|
||||
|
||||
impl Display for MacroString {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::String(s) => s.fmt(f),
|
||||
Self::MacroString(parts) => {
|
||||
for part in parts {
|
||||
match part {
|
||||
MacroStringPart::String(s) => s.fmt(f)?,
|
||||
MacroStringPart::MacroUsage(m) => write!(f, "$({m})")?,
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_program_identifier<S>(identifier: S) -> String
|
||||
where
|
||||
|
@ -71,3 +113,62 @@ where
|
|||
},
|
||||
})
|
||||
}
|
||||
|
||||
impl<S> From<S> for MacroString
|
||||
where
|
||||
S: Into<String>,
|
||||
{
|
||||
fn from(value: S) -> Self {
|
||||
Self::String(value.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&AnyStringLiteral> for MacroString {
|
||||
fn from(value: &AnyStringLiteral) -> Self {
|
||||
match value {
|
||||
AnyStringLiteral::StringLiteral(literal) => Self::from(literal.str_content().as_ref()),
|
||||
AnyStringLiteral::MacroStringLiteral(literal) => Self::from(literal),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AnyStringLiteral> for MacroString {
|
||||
fn from(value: AnyStringLiteral) -> Self {
|
||||
Self::from(&value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&MacroStringLiteral> for MacroString {
|
||||
fn from(value: &MacroStringLiteral) -> Self {
|
||||
if value
|
||||
.parts()
|
||||
.iter()
|
||||
.any(|p| matches!(p, MacroStringLiteralPart::MacroUsage { .. }))
|
||||
{
|
||||
Self::MacroString(
|
||||
value
|
||||
.parts()
|
||||
.iter()
|
||||
.map(|part| match part {
|
||||
MacroStringLiteralPart::Text(span) => MacroStringPart::String(
|
||||
crate::util::unescape_macro_string(span.str()).to_string(),
|
||||
),
|
||||
MacroStringLiteralPart::MacroUsage { identifier, .. } => {
|
||||
MacroStringPart::MacroUsage(
|
||||
crate::util::identifier_to_macro(identifier.span.str()).to_string(),
|
||||
)
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
} else {
|
||||
Self::String(value.str_content())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MacroStringLiteral> for MacroString {
|
||||
fn from(value: MacroStringLiteral) -> Self {
|
||||
Self::from(&value)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue