It compiles :o
This commit is contained in:
parent
c752cc928e
commit
4bf3c6fd63
47 changed files with 279 additions and 265 deletions
11
Cargo.lock
generated
11
Cargo.lock
generated
|
@ -436,6 +436,7 @@ dependencies = [
|
||||||
"debug_stub_derive",
|
"debug_stub_derive",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"dyn-clone",
|
"dyn-clone",
|
||||||
|
"eww_shared_util",
|
||||||
"extend",
|
"extend",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
@ -475,6 +476,14 @@ dependencies = [
|
||||||
"yuck",
|
"yuck",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "eww_shared_util"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"derive_more",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "extend"
|
name = "extend"
|
||||||
version = "1.1.1"
|
version = "1.1.1"
|
||||||
|
@ -1874,6 +1883,7 @@ dependencies = [
|
||||||
name = "simplexpr"
|
name = "simplexpr"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"eww_shared_util",
|
||||||
"insta",
|
"insta",
|
||||||
"itertools 0.10.1",
|
"itertools 0.10.1",
|
||||||
"lalrpop",
|
"lalrpop",
|
||||||
|
@ -2374,6 +2384,7 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"codespan-reporting",
|
"codespan-reporting",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
|
"eww_shared_util",
|
||||||
"insta",
|
"insta",
|
||||||
"itertools 0.10.1",
|
"itertools 0.10.1",
|
||||||
"lalrpop",
|
"lalrpop",
|
||||||
|
|
|
@ -2,5 +2,6 @@
|
||||||
members = [
|
members = [
|
||||||
"crates/eww",
|
"crates/eww",
|
||||||
"crates/simplexpr",
|
"crates/simplexpr",
|
||||||
"crates/yuck"
|
"crates/yuck",
|
||||||
|
"crates/eww_shared_util"
|
||||||
]
|
]
|
||||||
|
|
|
@ -69,6 +69,8 @@ notify = "5.0.0-pre.7"
|
||||||
|
|
||||||
simplexpr = { path = "../simplexpr" }
|
simplexpr = { path = "../simplexpr" }
|
||||||
yuck = { path = "../yuck" }
|
yuck = { path = "../yuck" }
|
||||||
|
eww_shared_util = { path = "../eww_shared_util" }
|
||||||
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions = "0.7.1"
|
pretty_assertions = "0.7.1"
|
||||||
|
|
|
@ -6,6 +6,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
use anyhow::*;
|
use anyhow::*;
|
||||||
use debug_stub_derive::*;
|
use debug_stub_derive::*;
|
||||||
|
use eww_shared_util::VarName;
|
||||||
use gdk::WindowExt;
|
use gdk::WindowExt;
|
||||||
use gtk::{ContainerExt, CssProviderExt, GtkWindowExt, StyleContextExt, WidgetExt};
|
use gtk::{ContainerExt, CssProviderExt, GtkWindowExt, StyleContextExt, WidgetExt};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
@ -14,7 +15,7 @@ use std::collections::HashMap;
|
||||||
use tokio::sync::mpsc::UnboundedSender;
|
use tokio::sync::mpsc::UnboundedSender;
|
||||||
use yuck::{
|
use yuck::{
|
||||||
config::window_geometry::{AnchorPoint, WindowGeometry},
|
config::window_geometry::{AnchorPoint, WindowGeometry},
|
||||||
value::{Coords, VarName},
|
value::Coords,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Response that the app may send as a response to a event.
|
/// Response that the app may send as a response to a event.
|
||||||
|
@ -112,30 +113,26 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DaemonCommand::ReloadConfigAndCss(sender) => {
|
DaemonCommand::ReloadConfigAndCss(sender) => {
|
||||||
|
let mut errors = Vec::new();
|
||||||
|
|
||||||
// TODO implement this
|
let config_result = EwwConfig::read_from_file(&self.paths.get_yuck_path());
|
||||||
//let mut errors = Vec::new();
|
match config_result {
|
||||||
todo!()
|
Ok(new_config) => self.handle_command(DaemonCommand::UpdateConfig(new_config)),
|
||||||
|
Err(e) => errors.push(e),
|
||||||
|
}
|
||||||
|
|
||||||
//let config_result =
|
let css_result = crate::util::parse_scss_from_file(&self.paths.get_eww_scss_path());
|
||||||
//EwwConfig::read_from_file(&self.paths.get_eww_xml_path()).and_then(config::EwwConfig::generate);
|
match css_result {
|
||||||
//match config_result {
|
Ok(new_css) => self.handle_command(DaemonCommand::UpdateCss(new_css)),
|
||||||
//Ok(new_config) => self.handle_command(DaemonCommand::UpdateConfig(new_config)),
|
Err(e) => errors.push(e),
|
||||||
//Err(e) => errors.push(e),
|
}
|
||||||
//}
|
|
||||||
|
|
||||||
//let css_result = crate::util::parse_scss_from_file(&self.paths.get_eww_scss_path());
|
let errors = errors.into_iter().map(|e| format!("{:?}", e)).join("\n");
|
||||||
//match css_result {
|
if errors.is_empty() {
|
||||||
//Ok(new_css) => self.handle_command(DaemonCommand::UpdateCss(new_css)),
|
sender.send(DaemonResponse::Success(String::new()))?;
|
||||||
//Err(e) => errors.push(e),
|
} else {
|
||||||
//}
|
sender.send(DaemonResponse::Failure(errors))?;
|
||||||
|
}
|
||||||
//let errors = errors.into_iter().map(|e| format!("{:?}", e)).join("\n");
|
|
||||||
//if errors.is_empty() {
|
|
||||||
//sender.send(DaemonResponse::Success(String::new()))?;
|
|
||||||
//} else {
|
|
||||||
//sender.send(DaemonResponse::Failure(errors))?;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
DaemonCommand::UpdateConfig(config) => {
|
DaemonCommand::UpdateConfig(config) => {
|
||||||
self.load_config(config)?;
|
self.load_config(config)?;
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
use anyhow::*;
|
use anyhow::*;
|
||||||
|
use eww_shared_util::VarName;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use yuck::{
|
use yuck::{
|
||||||
config::{script_var_definition::ScriptVarDefinition, widget_definition::WidgetDefinition},
|
config::{script_var_definition::ScriptVarDefinition, widget_definition::WidgetDefinition},
|
||||||
parser::from_ast::FromAst,
|
parser::from_ast::FromAst,
|
||||||
value::VarName,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use simplexpr::dynval::DynVal;
|
use simplexpr::dynval::DynVal;
|
||||||
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use super::{script_var, EwwWindowDefinition};
|
use super::{script_var, EwwWindowDefinition};
|
||||||
|
|
||||||
/// Eww configuration structure.
|
/// Eww configuration structure.
|
||||||
|
@ -19,33 +17,30 @@ pub struct EwwConfig {
|
||||||
windows: HashMap<String, EwwWindowDefinition>,
|
windows: HashMap<String, EwwWindowDefinition>,
|
||||||
initial_variables: HashMap<VarName, DynVal>,
|
initial_variables: HashMap<VarName, DynVal>,
|
||||||
script_vars: HashMap<VarName, ScriptVarDefinition>,
|
script_vars: HashMap<VarName, ScriptVarDefinition>,
|
||||||
pub filepath: PathBuf,
|
|
||||||
}
|
}
|
||||||
impl EwwConfig {
|
impl EwwConfig {
|
||||||
pub fn read_from_file<P: AsRef<std::path::Path>>(path: P) -> Result<Self> {
|
pub fn read_from_file<P: AsRef<std::path::Path>>(path: P) -> Result<Self> {
|
||||||
let content = std::fs::read_to_string(path)?;
|
let content = std::fs::read_to_string(path)?;
|
||||||
let ast = yuck::parser::parse_string(0, &content)?;
|
let ast = yuck::parser::parse_toplevel(0, &content)?;
|
||||||
let config = yuck::config::Config::from_ast(ast)?;
|
let config = yuck::config::Config::from_ast(ast)?;
|
||||||
Self::generate(config)
|
Self::generate(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate(config: yuck::config::Config) -> Result<Self> {
|
pub fn generate(config: yuck::config::Config) -> Result<Self> {
|
||||||
|
let yuck::config::Config { widget_definitions, window_definitions, var_definitions, script_vars } = config;
|
||||||
Ok(EwwConfig {
|
Ok(EwwConfig {
|
||||||
windows: config
|
windows: window_definitions
|
||||||
.window_definitions
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(name, window)| {
|
.map(|(name, window)| {
|
||||||
Ok((
|
Ok((
|
||||||
name,
|
name,
|
||||||
EwwWindowDefinition::generate(&config.widget_definitions, window)
|
EwwWindowDefinition::generate(&widget_definitions, window).context("Failed expand window definition")?,
|
||||||
.context("Failed expand window definition")?,
|
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.collect::<Result<HashMap<_, _>>>()?,
|
.collect::<Result<HashMap<_, _>>>()?,
|
||||||
widgets: config.widget_definitions,
|
widgets: widget_definitions,
|
||||||
initial_variables: config.var_definitions.into_iter().map(|(k, v)| (k, v.initial_value)).collect(),
|
initial_variables: var_definitions.into_iter().map(|(k, v)| (k, v.initial_value)).collect(),
|
||||||
script_vars: config.script_vars,
|
script_vars,
|
||||||
filepath: todo!(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
use std::{collections::HashMap, time::Duration};
|
use std::{collections::HashMap, time::Duration};
|
||||||
|
|
||||||
use simplexpr::dynval::DynVal;
|
use simplexpr::dynval::DynVal;
|
||||||
use yuck::{
|
use yuck::config::script_var_definition::{PollScriptVar, ScriptVarDefinition, VarSource};
|
||||||
config::script_var_definition::{PollScriptVar, ScriptVarDefinition, VarSource},
|
|
||||||
value::VarName,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::config::system_stats::*;
|
use crate::config::system_stats::*;
|
||||||
|
use eww_shared_util::VarName;
|
||||||
|
|
||||||
macro_rules! builtin_vars {
|
macro_rules! builtin_vars {
|
||||||
($interval:expr, $($name:literal => $fun:expr),*$(,)?) => {{
|
($interval:expr, $($name:literal => $fun:expr),*$(,)?) => {{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use anyhow::*;
|
use anyhow::*;
|
||||||
|
use eww_shared_util::{AttrName, VarName};
|
||||||
use std::{collections::HashMap, sync::Arc};
|
use std::{collections::HashMap, sync::Arc};
|
||||||
use yuck::value::{AttrName, VarName};
|
|
||||||
|
|
||||||
use simplexpr::{dynval::DynVal, SimplExpr};
|
use simplexpr::{dynval::DynVal, SimplExpr};
|
||||||
|
|
||||||
|
@ -12,9 +12,8 @@ pub struct StateChangeHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StateChangeHandler {
|
impl StateChangeHandler {
|
||||||
fn used_variables(&self) -> impl Iterator<Item = VarName> + '_ {
|
fn used_variables(&self) -> impl Iterator<Item = &VarName> {
|
||||||
// TODO fix this clone
|
self.unresolved_values.iter().flat_map(|(_, value)| value.var_refs())
|
||||||
self.unresolved_values.iter().flat_map(|(_, value)| value.var_refs()).map(|x| VarName(x.to_string()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run the StateChangeHandler.
|
/// Run the StateChangeHandler.
|
||||||
|
@ -24,7 +23,7 @@ impl StateChangeHandler {
|
||||||
.unresolved_values
|
.unresolved_values
|
||||||
.clone()
|
.clone()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(attr_name, value)| Ok((attr_name, value.resolve_fully(state)?)))
|
.map(|(attr_name, value)| Ok((attr_name, value.eval(state)?)))
|
||||||
.collect::<Result<_>>();
|
.collect::<Result<_>>();
|
||||||
|
|
||||||
match resolved_attrs {
|
match resolved_attrs {
|
||||||
|
@ -107,8 +106,7 @@ impl EwwState {
|
||||||
|
|
||||||
/// resolves a value if possible, using the current eww_state.
|
/// resolves a value if possible, using the current eww_state.
|
||||||
pub fn resolve_once<'a>(&'a self, value: &'a SimplExpr) -> Result<DynVal> {
|
pub fn resolve_once<'a>(&'a self, value: &'a SimplExpr) -> Result<DynVal> {
|
||||||
// TODO fix this clone
|
Ok(value.clone().eval(&self.variables_state)?)
|
||||||
Ok(value.clone().eval(&self.variables_state.into_iter().map(|(k, v)| (k.0, v)).collect())?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve takes a function that applies a set of fully resolved attribute
|
/// Resolve takes a function that applies a set of fully resolved attribute
|
||||||
|
|
|
@ -162,8 +162,8 @@ impl EwwPaths {
|
||||||
self.config_dir.as_path()
|
self.config_dir.as_path()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_eww_xml_path(&self) -> PathBuf {
|
pub fn get_yuck_path(&self) -> PathBuf {
|
||||||
self.config_dir.join("eww.xml")
|
self.config_dir.join("eww.yuck")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_eww_scss_path(&self) -> PathBuf {
|
pub fn get_eww_scss_path(&self) -> PathBuf {
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
use anyhow::*;
|
use anyhow::*;
|
||||||
|
use eww_shared_util::VarName;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use simplexpr::dynval::DynVal;
|
use simplexpr::dynval::DynVal;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
use yuck::{
|
use yuck::{config::window_geometry::AnchorPoint, value::Coords};
|
||||||
config::window_geometry::AnchorPoint,
|
|
||||||
value::{Coords, VarName},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::app;
|
use crate::app;
|
||||||
|
|
||||||
|
@ -23,7 +21,7 @@ struct RawOpt {
|
||||||
#[structopt(long = "debug", global = true)]
|
#[structopt(long = "debug", global = true)]
|
||||||
log_debug: bool,
|
log_debug: bool,
|
||||||
|
|
||||||
/// override path to configuration directory (directory that contains eww.xml and eww.scss)
|
/// override path to configuration directory (directory that contains eww.yuck and eww.scss)
|
||||||
#[structopt(short, long, global = true)]
|
#[structopt(short, long, global = true)]
|
||||||
config: Option<std::path::PathBuf>,
|
config: Option<std::path::PathBuf>,
|
||||||
|
|
||||||
|
@ -153,7 +151,7 @@ fn parse_var_update_arg(s: &str) -> Result<(VarName, DynVal)> {
|
||||||
impl ActionWithServer {
|
impl ActionWithServer {
|
||||||
pub fn into_daemon_command(self) -> (app::DaemonCommand, Option<app::DaemonResponseReceiver>) {
|
pub fn into_daemon_command(self) -> (app::DaemonCommand, Option<app::DaemonResponseReceiver>) {
|
||||||
let command = match self {
|
let command = match self {
|
||||||
ActionWithServer::Update { mappings } => app::DaemonCommand::UpdateVars(mappings.into_iter().collect()),
|
ActionWithServer::Update { mappings } => app::DaemonCommand::UpdateVars(mappings),
|
||||||
|
|
||||||
ActionWithServer::KillServer => app::DaemonCommand::KillServer,
|
ActionWithServer::KillServer => app::DaemonCommand::KillServer,
|
||||||
ActionWithServer::CloseAll => app::DaemonCommand::CloseAll,
|
ActionWithServer::CloseAll => app::DaemonCommand::CloseAll,
|
||||||
|
|
|
@ -4,13 +4,14 @@ use crate::app;
|
||||||
use anyhow::*;
|
use anyhow::*;
|
||||||
use app::DaemonCommand;
|
use app::DaemonCommand;
|
||||||
|
|
||||||
|
use eww_shared_util::VarName;
|
||||||
use simplexpr::dynval::DynVal;
|
use simplexpr::dynval::DynVal;
|
||||||
use tokio::{
|
use tokio::{
|
||||||
io::{AsyncBufReadExt, BufReader},
|
io::{AsyncBufReadExt, BufReader},
|
||||||
sync::mpsc::UnboundedSender,
|
sync::mpsc::UnboundedSender,
|
||||||
};
|
};
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
use yuck::{config::script_var_definition::{PollScriptVar, ScriptVarDefinition, TailScriptVar}, value::VarName};
|
use yuck::config::script_var_definition::{PollScriptVar, ScriptVarDefinition, TailScriptVar};
|
||||||
|
|
||||||
/// Initialize the script var handler, and return a handle to that handler, which can be used to control
|
/// Initialize the script var handler, and return a handle to that handler, which can be used to control
|
||||||
/// the script var execution.
|
/// the script var execution.
|
||||||
|
|
|
@ -27,7 +27,7 @@ pub fn initialize_server(paths: EwwPaths) -> Result<()> {
|
||||||
.with_context(|| format!("Failed to change working directory to {}", paths.get_config_dir().display()))?;
|
.with_context(|| format!("Failed to change working directory to {}", paths.get_config_dir().display()))?;
|
||||||
|
|
||||||
log::info!("Loading paths: {}", &paths);
|
log::info!("Loading paths: {}", &paths);
|
||||||
let eww_config = config::EwwConfig::read_from_file(&paths.get_eww_xml_path())?;
|
let eww_config = config::EwwConfig::read_from_file(&paths.get_yuck_path())?;
|
||||||
|
|
||||||
gtk::init()?;
|
gtk::init()?;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use crate::eww_state::*;
|
use crate::eww_state::*;
|
||||||
use anyhow::*;
|
use anyhow::*;
|
||||||
|
use eww_shared_util::AttrName;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use yuck::{config::widget_definition::WidgetDefinition, value::AttrName};
|
use yuck::config::widget_definition::WidgetDefinition;
|
||||||
|
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use widget_definitions::*;
|
use widget_definitions::*;
|
||||||
|
@ -129,7 +130,7 @@ macro_rules! resolve_block {
|
||||||
let attr_map: Result<_> = try {
|
let attr_map: Result<_> = try {
|
||||||
::maplit::hashmap! {
|
::maplit::hashmap! {
|
||||||
$(
|
$(
|
||||||
yuck::value::AttrName(::std::stringify!($attr_name).to_owned()) =>
|
eww_shared_util::AttrName(::std::stringify!($attr_name).to_owned()) =>
|
||||||
resolve_block!(@get_value $args, &::std::stringify!($attr_name).replace('_', "-"), $(= $default)?)
|
resolve_block!(@get_value $args, &::std::stringify!($attr_name).replace('_', "-"), $(= $default)?)
|
||||||
),*
|
),*
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#![allow(clippy::option_map_unit_fn)]
|
#![allow(clippy::option_map_unit_fn)]
|
||||||
use super::{run_command, BuilderArgs};
|
use super::{run_command, BuilderArgs};
|
||||||
use crate::{
|
use crate::{
|
||||||
config, enum_parse, eww_state, resolve_block,
|
enum_parse, eww_state, resolve_block,
|
||||||
util::{list_difference, parse_duration},
|
util::{list_difference, parse_duration},
|
||||||
widgets::widget_node,
|
widgets::widget_node,
|
||||||
};
|
};
|
||||||
|
@ -10,6 +10,7 @@ use gdk::WindowExt;
|
||||||
use glib;
|
use glib;
|
||||||
use gtk::{self, prelude::*, ImageExt};
|
use gtk::{self, prelude::*, ImageExt};
|
||||||
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||||
|
use yuck::parser::from_ast::FromAst;
|
||||||
|
|
||||||
// TODO figure out how to
|
// TODO figure out how to
|
||||||
// TODO https://developer.gnome.org/gtk3/stable/GtkFixed.html
|
// TODO https://developer.gnome.org/gtk3/stable/GtkFixed.html
|
||||||
|
@ -244,12 +245,13 @@ fn build_gtk_combo_box_text(bargs: &mut BuilderArgs) -> Result<gtk::ComboBoxText
|
||||||
let on_change_handler_id: Rc<RefCell<Option<glib::SignalHandlerId>>> = Rc::new(RefCell::new(None));
|
let on_change_handler_id: Rc<RefCell<Option<glib::SignalHandlerId>>> = Rc::new(RefCell::new(None));
|
||||||
resolve_block!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
// @prop items - Items that should be displayed in the combo box
|
// @prop items - Items that should be displayed in the combo box
|
||||||
prop(items: as_vec) {
|
// TODO reimplement, obviously
|
||||||
gtk_widget.remove_all();
|
//prop(items: as_vec) {
|
||||||
for i in items {
|
//gtk_widget.remove_all();
|
||||||
gtk_widget.append_text(&i);
|
//for i in items {
|
||||||
}
|
//gtk_widget.append_text(&i);
|
||||||
},
|
//}
|
||||||
|
//},
|
||||||
// @prop onchange - runs the code when a item was selected, replacing {} with the item as a string
|
// @prop onchange - runs the code when a item was selected, replacing {} with the item as a string
|
||||||
prop(onchange: as_string) {
|
prop(onchange: as_string) {
|
||||||
let old_id = on_change_handler_id.replace(Some(
|
let old_id = on_change_handler_id.replace(Some(
|
||||||
|
@ -518,15 +520,16 @@ fn build_gtk_literal(bargs: &mut BuilderArgs) -> Result<gtk::Box> {
|
||||||
gtk_widget.set_widget_name("literal");
|
gtk_widget.set_widget_name("literal");
|
||||||
|
|
||||||
// TODO these clones here are dumdum
|
// TODO these clones here are dumdum
|
||||||
let window_name = bargs.window_name.clone();
|
let window_name = bargs.window_name.to_string();
|
||||||
let widget_definitions = bargs.widget_definitions.clone();
|
let widget_definitions = bargs.widget_definitions.clone();
|
||||||
|
|
||||||
resolve_block!(bargs, gtk_widget, {
|
resolve_block!(bargs, gtk_widget, {
|
||||||
// @prop content - inline Eww XML that will be rendered as a widget.
|
// @prop content - inline Eww XML that will be rendered as a widget.
|
||||||
prop(content: as_string) {
|
prop(content: as_string) {
|
||||||
gtk_widget.get_children().iter().for_each(|w| gtk_widget.remove(w));
|
gtk_widget.get_children().iter().for_each(|w| gtk_widget.remove(w));
|
||||||
if !content.is_empty() {
|
if !content.is_empty() {
|
||||||
let document = roxmltree::Document::parse(&content).map_err(|e| anyhow!("Failed to parse eww xml literal: {:?}", e))?;
|
let ast = yuck::parser::parse_string(usize::MAX, &content)?;
|
||||||
let content_widget_use = config::element::WidgetUse::from_xml_node(document.root_element().into())?;
|
let content_widget_use = yuck::config::widget_use::WidgetUse::from_ast(ast)?;
|
||||||
|
|
||||||
let widget_node = &*widget_node::generate_generic_widget_node(&widget_definitions, &HashMap::new(), content_widget_use)?;
|
let widget_node = &*widget_node::generate_generic_widget_node(&widget_definitions, &HashMap::new(), content_widget_use)?;
|
||||||
let child_widget = widget_node.render(&mut eww_state::EwwState::default(), &window_name, &widget_definitions)?;
|
let child_widget = widget_node.render(&mut eww_state::EwwState::default(), &window_name, &widget_definitions)?;
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
use crate::eww_state::EwwState;
|
use crate::eww_state::EwwState;
|
||||||
use anyhow::*;
|
use anyhow::*;
|
||||||
use dyn_clone;
|
use dyn_clone;
|
||||||
|
use eww_shared_util::{AttrName, Span, VarName};
|
||||||
use simplexpr::SimplExpr;
|
use simplexpr::SimplExpr;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use yuck::{
|
use yuck::config::{widget_definition::WidgetDefinition, widget_use::WidgetUse};
|
||||||
config::{widget_definition::WidgetDefinition, widget_use::WidgetUse},
|
|
||||||
parser::ast::Span,
|
|
||||||
value::{AttrName, VarName},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub trait WidgetNode: std::fmt::Debug + dyn_clone::DynClone + Send + Sync {
|
pub trait WidgetNode: std::fmt::Debug + dyn_clone::DynClone + Send + Sync {
|
||||||
fn get_name(&self) -> &str;
|
fn get_name(&self) -> &str;
|
||||||
|
@ -70,9 +67,8 @@ impl Generic {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// returns all the variables that are referenced in this widget
|
/// returns all the variables that are referenced in this widget
|
||||||
pub fn referenced_vars(&self) -> impl Iterator<Item = VarName> + '_ {
|
pub fn referenced_vars(&self) -> impl Iterator<Item = &VarName> {
|
||||||
// TODO fix this clone
|
self.attrs.iter().flat_map(|(_, value)| value.var_refs())
|
||||||
self.attrs.iter().flat_map(|(_, value)| value.var_refs()).map(|x| VarName(x.to_string()))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,12 +104,7 @@ pub fn generate_generic_widget_node(
|
||||||
.attrs
|
.attrs
|
||||||
.attrs
|
.attrs
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(name, value)| {
|
.map(|(name, value)| Ok((VarName(name.0), value.value.as_simplexpr()?.resolve_one_level(local_env))))
|
||||||
Ok((
|
|
||||||
VarName(name.0),
|
|
||||||
SimplExpr::Literal(value.value.span().into(), value.value.as_simplexpr()?.resolve_one_level(local_env)?),
|
|
||||||
))
|
|
||||||
})
|
|
||||||
.collect::<Result<HashMap<VarName, _>>>()?;
|
.collect::<Result<HashMap<VarName, _>>>()?;
|
||||||
|
|
||||||
let content = generate_generic_widget_node(defs, &new_local_env, def.widget.clone())?;
|
let content = generate_generic_widget_node(defs, &new_local_env, def.widget.clone())?;
|
||||||
|
@ -126,13 +117,8 @@ pub fn generate_generic_widget_node(
|
||||||
.attrs
|
.attrs
|
||||||
.attrs
|
.attrs
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(name, value)| {
|
.map(|(name, value)| Ok((name, value.value.as_simplexpr()?.resolve_one_level(local_env))))
|
||||||
Ok((
|
.collect::<Result<HashMap<_, _>>>()?,
|
||||||
VarName(name.0),
|
|
||||||
SimplExpr::Literal(value.value.span().into(), value.value.as_simplexpr()?.resolve_one_level(local_env)?),
|
|
||||||
))
|
|
||||||
})
|
|
||||||
.collect()?,
|
|
||||||
|
|
||||||
children: w
|
children: w
|
||||||
.children
|
.children
|
||||||
|
|
8
crates/eww_shared_util/Cargo.toml
Normal file
8
crates/eww_shared_util/Cargo.toml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[package]
|
||||||
|
name = "eww_shared_util"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = {version = "1.0", features = ["derive"]}
|
||||||
|
derive_more = "0.99"
|
5
crates/eww_shared_util/src/lib.rs
Normal file
5
crates/eww_shared_util/src/lib.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
pub mod span;
|
||||||
|
pub mod wrappers;
|
||||||
|
|
||||||
|
pub use span::*;
|
||||||
|
pub use wrappers::*;
|
36
crates/eww_shared_util/src/span.rs
Normal file
36
crates/eww_shared_util/src/span.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#[derive(Eq, PartialEq, Clone, Copy, serde::Serialize, serde::Deserialize)]
|
||||||
|
pub struct Span(pub usize, pub usize, pub usize);
|
||||||
|
pub static DUMMY_SPAN: Span = Span(usize::MAX, usize::MAX, usize::MAX);
|
||||||
|
|
||||||
|
impl Span {
|
||||||
|
/// Get the span that includes this and the other span completely.
|
||||||
|
/// Will panic if the spans are from different file_ids.
|
||||||
|
pub fn to(mut self, other: Span) -> Self {
|
||||||
|
assert!(other.2 == self.2);
|
||||||
|
self.1 = other.1;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ending_at(mut self, end: usize) -> Self {
|
||||||
|
self.1 = end;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Turn this span into a span only highlighting the point it starts at, setting the length to 0.
|
||||||
|
pub fn point_span(mut self) -> Self {
|
||||||
|
self.1 = self.0;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for Span {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}..{}", self.0, self.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Span {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}..{}", self.0, self.1)
|
||||||
|
}
|
||||||
|
}
|
42
crates/eww_shared_util/src/wrappers.rs
Normal file
42
crates/eww_shared_util/src/wrappers.rs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
use derive_more::*;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// The name of a variable
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(
|
||||||
|
Clone, Hash, PartialEq, Eq, Serialize, Deserialize, AsRef, From, FromStr, Display, DebugCustom,
|
||||||
|
)]
|
||||||
|
#[debug(fmt = "VarName({})", .0)]
|
||||||
|
pub struct VarName(pub String);
|
||||||
|
|
||||||
|
impl std::borrow::Borrow<str> for VarName {
|
||||||
|
fn borrow(&self) -> &str {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for VarName {
|
||||||
|
fn from(s: &str) -> Self {
|
||||||
|
VarName(s.to_owned())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The name of an attribute
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(
|
||||||
|
Clone, Hash, PartialEq, Eq, Serialize, Deserialize, AsRef, From, FromStr, Display, DebugCustom,
|
||||||
|
)]
|
||||||
|
#[debug(fmt="AttrName({})", .0)]
|
||||||
|
pub struct AttrName(pub String);
|
||||||
|
|
||||||
|
impl std::borrow::Borrow<str> for AttrName {
|
||||||
|
fn borrow(&self) -> &str {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for AttrName {
|
||||||
|
fn from(s: &str) -> Self {
|
||||||
|
AttrName(s.to_owned())
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ serde_json = "1.0"
|
||||||
|
|
||||||
strum = { version = "0.21", features = ["derive"] }
|
strum = { version = "0.21", features = ["derive"] }
|
||||||
|
|
||||||
|
eww_shared_util = { path = "../eww_shared_util" }
|
||||||
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
|
|
@ -1,23 +1,9 @@
|
||||||
use crate::dynval::DynVal;
|
use crate::dynval::DynVal;
|
||||||
|
use eww_shared_util::{Span, DUMMY_SPAN};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// stores the left and right end of a span, and a given file identifier.
|
use eww_shared_util::VarName;
|
||||||
#[derive(Eq, PartialEq, Clone, Copy, Serialize, Deserialize)]
|
|
||||||
pub struct Span(pub usize, pub usize, pub usize);
|
|
||||||
pub static DUMMY_SPAN: Span = Span(usize::MAX, usize::MAX, usize::MAX);
|
|
||||||
|
|
||||||
impl std::fmt::Display for Span {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(f, "{}..{}", self.0, self.1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::fmt::Debug for Span {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(f, "{}..{}", self.0, self.1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug, strum::EnumString, strum::Display)]
|
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug, strum::EnumString, strum::Display)]
|
||||||
|
@ -46,7 +32,7 @@ pub enum UnaryOp {
|
||||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub enum SimplExpr {
|
pub enum SimplExpr {
|
||||||
Literal(Span, DynVal),
|
Literal(Span, DynVal),
|
||||||
VarRef(Span, String),
|
VarRef(Span, VarName),
|
||||||
BinOp(Span, Box<SimplExpr>, BinOp, Box<SimplExpr>),
|
BinOp(Span, Box<SimplExpr>, BinOp, Box<SimplExpr>),
|
||||||
UnaryOp(Span, UnaryOp, Box<SimplExpr>),
|
UnaryOp(Span, UnaryOp, Box<SimplExpr>),
|
||||||
IfElse(Span, Box<SimplExpr>, Box<SimplExpr>, Box<SimplExpr>),
|
IfElse(Span, Box<SimplExpr>, Box<SimplExpr>, Box<SimplExpr>),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::ast::Span;
|
use eww_shared_util::Span;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{fmt, iter::FromIterator, str::FromStr};
|
use std::{fmt, iter::FromIterator, str::FromStr};
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::Span,
|
|
||||||
dynval,
|
dynval,
|
||||||
parser::lexer::{self, LexicalError},
|
parser::lexer::{self, LexicalError},
|
||||||
};
|
};
|
||||||
|
use eww_shared_util::Span;
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{BinOp, SimplExpr, Span, UnaryOp},
|
ast::{BinOp, SimplExpr, UnaryOp},
|
||||||
dynval::{ConversionError, DynVal},
|
dynval::{ConversionError, DynVal},
|
||||||
};
|
};
|
||||||
|
use eww_shared_util::{Span, VarName};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
@ -50,13 +51,6 @@ impl EvalError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type VarName = String;
|
|
||||||
|
|
||||||
pub trait FunctionSource {
|
|
||||||
type Err;
|
|
||||||
fn run_fn(&self, name: &str, args: &[DynVal]) -> Result<DynVal, Self::Err>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SimplExpr {
|
impl SimplExpr {
|
||||||
pub fn map_terminals_into(self, f: impl Fn(Self) -> Self) -> Self {
|
pub fn map_terminals_into(self, f: impl Fn(Self) -> Self) -> Self {
|
||||||
use SimplExpr::*;
|
use SimplExpr::*;
|
||||||
|
@ -70,6 +64,36 @@ impl SimplExpr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// map over all of the variable references, replacing them with whatever expression the provided function returns.
|
||||||
|
/// Returns [Err] when the provided function fails with an [Err]
|
||||||
|
pub fn try_map_var_refs<E, F: Fn(Span, VarName) -> Result<SimplExpr, E> + Copy>(self, f: F) -> Result<Self, E> {
|
||||||
|
use SimplExpr::*;
|
||||||
|
Ok(match self {
|
||||||
|
BinOp(span, box a, op, box b) => BinOp(span, box a.try_map_var_refs(f)?, op, box b.try_map_var_refs(f)?),
|
||||||
|
UnaryOp(span, op, box a) => UnaryOp(span, op, box a.try_map_var_refs(f)?),
|
||||||
|
IfElse(span, box a, box b, box c) => {
|
||||||
|
IfElse(span, box a.try_map_var_refs(f)?, box b.try_map_var_refs(f)?, box c.try_map_var_refs(f)?)
|
||||||
|
}
|
||||||
|
JsonAccess(span, box a, box b) => JsonAccess(span, box a.try_map_var_refs(f)?, box b.try_map_var_refs(f)?),
|
||||||
|
FunctionCall(span, name, args) => {
|
||||||
|
FunctionCall(span, name, args.into_iter().map(|x| x.try_map_var_refs(f)).collect::<Result<_, _>>()?)
|
||||||
|
}
|
||||||
|
VarRef(span, name) => f(span, name)?,
|
||||||
|
x @ Literal(..) => x,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn map_var_refs(self, f: impl Fn(Span, VarName) -> SimplExpr) -> Self {
|
||||||
|
self.try_map_var_refs(|span, var| Ok::<_, !>(f(span, var))).into_ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// resolve partially.
|
||||||
|
/// If a var-ref links to another var-ref, that other var-ref is used.
|
||||||
|
/// If a referenced variable is not found in the given hashmap, returns the var-ref unchanged.
|
||||||
|
pub fn resolve_one_level(self, variables: &HashMap<VarName, SimplExpr>) -> Self {
|
||||||
|
self.map_var_refs(|span, name| variables.get(&name).cloned().unwrap_or_else(|| Self::VarRef(span, name)))
|
||||||
|
}
|
||||||
|
|
||||||
/// resolve variable references in the expression. Fails if a variable cannot be resolved.
|
/// resolve variable references in the expression. Fails if a variable cannot be resolved.
|
||||||
pub fn resolve_refs(self, variables: &HashMap<VarName, DynVal>) -> Result<Self, EvalError> {
|
pub fn resolve_refs(self, variables: &HashMap<VarName, DynVal>) -> Result<Self, EvalError> {
|
||||||
use SimplExpr::*;
|
use SimplExpr::*;
|
||||||
|
@ -96,7 +120,7 @@ impl SimplExpr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn var_refs(&self) -> Vec<&String> {
|
pub fn var_refs(&self) -> Vec<&VarName> {
|
||||||
use SimplExpr::*;
|
use SimplExpr::*;
|
||||||
match self {
|
match self {
|
||||||
Literal(..) => Vec::new(),
|
Literal(..) => Vec::new(),
|
||||||
|
@ -130,7 +154,7 @@ impl SimplExpr {
|
||||||
let value = match self {
|
let value = match self {
|
||||||
SimplExpr::Literal(_, x) => Ok(x.clone()),
|
SimplExpr::Literal(_, x) => Ok(x.clone()),
|
||||||
SimplExpr::VarRef(span, ref name) => {
|
SimplExpr::VarRef(span, ref name) => {
|
||||||
Ok(values.get(name).cloned().ok_or_else(|| EvalError::UnresolvedVariable(name.to_string()).at(*span))?.at(*span))
|
Ok(values.get(name).cloned().ok_or_else(|| EvalError::UnresolvedVariable(name.clone()).at(*span))?.at(*span))
|
||||||
}
|
}
|
||||||
SimplExpr::BinOp(_, a, op, b) => {
|
SimplExpr::BinOp(_, a, op, b) => {
|
||||||
let a = a.eval(values)?;
|
let a = a.eval(values)?;
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
#![feature(try_blocks)]
|
#![feature(try_blocks)]
|
||||||
|
#![feature(unwrap_infallible)]
|
||||||
|
#![feature(never_type)]
|
||||||
|
|
||||||
pub mod ast;
|
pub mod ast;
|
||||||
pub mod dynval;
|
pub mod dynval;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod eval;
|
pub mod eval;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
|
|
||||||
pub use ast::{SimplExpr, Span};
|
pub use ast::SimplExpr;
|
||||||
|
|
||||||
use lalrpop_util::lalrpop_mod;
|
use lalrpop_util::lalrpop_mod;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::ast::{SimplExpr::{self, *}, Span, BinOp::*, UnaryOp::*};
|
use crate::ast::{SimplExpr::{self, *}, BinOp::*, UnaryOp::*};
|
||||||
|
use eww_shared_util::{Span, VarName};
|
||||||
use crate::parser::lexer::{Token, LexicalError};
|
use crate::parser::lexer::{Token, LexicalError};
|
||||||
use crate::parser::lalrpop_helpers::*;
|
use crate::parser::lalrpop_helpers::*;
|
||||||
use lalrpop_util::ParseError;
|
use lalrpop_util::ParseError;
|
||||||
|
@ -66,7 +67,7 @@ pub Expr: SimplExpr = {
|
||||||
},
|
},
|
||||||
|
|
||||||
<Literal>,
|
<Literal>,
|
||||||
<l:@L> <ident:"identifier"> <r:@R> => VarRef(Span(l, r, fid), ident.to_string()),
|
<l:@L> <ident:"identifier"> <r:@R> => VarRef(Span(l, r, fid), VarName(ident.to_string())),
|
||||||
"(" <ExprReset> ")",
|
"(" <ExprReset> ")",
|
||||||
|
|
||||||
#[precedence(level="1")] #[assoc(side="right")]
|
#[precedence(level="1")] #[assoc(side="right")]
|
||||||
|
|
|
@ -27,6 +27,7 @@ static_assertions = "1.1"
|
||||||
|
|
||||||
|
|
||||||
simplexpr = { path = "../simplexpr" }
|
simplexpr = { path = "../simplexpr" }
|
||||||
|
eww_shared_util = { path = "../eww_shared_util" }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
lalrpop = "0.19.5"
|
lalrpop = "0.19.5"
|
||||||
|
|
|
@ -11,12 +11,9 @@ use simplexpr::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::AstError,
|
error::AstError,
|
||||||
parser::{
|
parser::{ast::Ast, from_ast::FromAst},
|
||||||
ast::{Ast, Span},
|
|
||||||
from_ast::FromAst,
|
|
||||||
},
|
|
||||||
value::AttrName,
|
|
||||||
};
|
};
|
||||||
|
use eww_shared_util::{AttrName, Span, VarName};
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum AttrError {
|
pub enum AttrError {
|
||||||
|
|
|
@ -5,13 +5,10 @@ use anyhow::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
enum_parse,
|
enum_parse,
|
||||||
error::AstResult,
|
error::AstResult,
|
||||||
parser::{
|
parser::{ast::Ast, ast_iterator::AstIterator, from_ast::FromAstElementContent},
|
||||||
ast::{Ast, Span},
|
|
||||||
ast_iterator::AstIterator,
|
|
||||||
from_ast::FromAstElementContent,
|
|
||||||
},
|
|
||||||
value::NumWithUnit,
|
value::NumWithUnit,
|
||||||
};
|
};
|
||||||
|
use eww_shared_util::Span;
|
||||||
|
|
||||||
use super::{attributes::Attributes, window_definition::EnumParseError};
|
use super::{attributes::Attributes, window_definition::EnumParseError};
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,12 @@ use crate::{
|
||||||
config::script_var_definition::{PollScriptVar, TailScriptVar},
|
config::script_var_definition::{PollScriptVar, TailScriptVar},
|
||||||
error::{AstError, AstResult, OptionAstErrorExt},
|
error::{AstError, AstResult, OptionAstErrorExt},
|
||||||
parser::{
|
parser::{
|
||||||
ast::{Ast, Span},
|
ast::Ast,
|
||||||
ast_iterator::AstIterator,
|
ast_iterator::AstIterator,
|
||||||
from_ast::{FromAst, FromAstElementContent},
|
from_ast::{FromAst, FromAstElementContent},
|
||||||
},
|
},
|
||||||
value::{AttrName, VarName},
|
|
||||||
};
|
};
|
||||||
|
use eww_shared_util::{AttrName, Span, VarName};
|
||||||
|
|
||||||
pub enum TopLevel {
|
pub enum TopLevel {
|
||||||
VarDefinition(VarDefinition),
|
VarDefinition(VarDefinition),
|
||||||
|
|
|
@ -5,12 +5,12 @@ use simplexpr::{dynval::DynVal, SimplExpr};
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{AstError, AstResult},
|
error::{AstError, AstResult},
|
||||||
parser::{
|
parser::{
|
||||||
ast::{Ast, Span},
|
ast::Ast,
|
||||||
ast_iterator::AstIterator,
|
ast_iterator::AstIterator,
|
||||||
from_ast::{FromAst, FromAstElementContent},
|
from_ast::{FromAst, FromAstElementContent},
|
||||||
},
|
},
|
||||||
value::{AttrName, VarName},
|
|
||||||
};
|
};
|
||||||
|
use eww_shared_util::{AttrName, Span, VarName};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
|
||||||
pub enum ScriptVarDefinition {
|
pub enum ScriptVarDefinition {
|
||||||
|
|
|
@ -1,16 +1,11 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
config::config::Config,
|
config::config::Config,
|
||||||
parser::{
|
parser::{self, ast::Ast, from_ast::FromAst, lexer::Lexer},
|
||||||
self,
|
|
||||||
ast::{Ast, Span},
|
|
||||||
from_ast::FromAst,
|
|
||||||
lexer::Lexer,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_config() {
|
fn test_config() {
|
||||||
let input = r#"
|
let input = r#"
|
||||||
(defwidget foo [arg]
|
(defwidget foo [arg]
|
||||||
"heyho")
|
"heyho")
|
||||||
(defwidget bar [arg arg2]
|
(defwidget bar [arg arg2]
|
||||||
|
|
|
@ -4,15 +4,11 @@ use simplexpr::SimplExpr;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::AstResult,
|
error::AstResult,
|
||||||
parser::{
|
parser::{ast::Ast, ast_iterator::AstIterator, from_ast::FromAst},
|
||||||
ast::{Ast, Span},
|
|
||||||
ast_iterator::AstIterator,
|
|
||||||
from_ast::FromAst,
|
|
||||||
},
|
|
||||||
value::{AttrName, VarName},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{widget_definition::WidgetDefinition, widget_use::WidgetUse};
|
use super::{widget_definition::WidgetDefinition, widget_use::WidgetUse};
|
||||||
|
use eww_shared_util::{AttrName, Span, VarName};
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum ValidationError {
|
pub enum ValidationError {
|
||||||
|
|
|
@ -5,12 +5,12 @@ use simplexpr::{dynval::DynVal, SimplExpr};
|
||||||
use crate::{
|
use crate::{
|
||||||
error::AstResult,
|
error::AstResult,
|
||||||
parser::{
|
parser::{
|
||||||
ast::{Ast, Span},
|
ast::Ast,
|
||||||
ast_iterator::AstIterator,
|
ast_iterator::AstIterator,
|
||||||
from_ast::{FromAst, FromAstElementContent},
|
from_ast::{FromAst, FromAstElementContent},
|
||||||
},
|
},
|
||||||
value::{AttrName, VarName},
|
|
||||||
};
|
};
|
||||||
|
use eww_shared_util::{AttrName, Span, VarName};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, serde::Serialize)]
|
#[derive(Debug, PartialEq, Eq, Clone, serde::Serialize)]
|
||||||
pub struct VarDefinition {
|
pub struct VarDefinition {
|
||||||
|
|
|
@ -5,12 +5,12 @@ use simplexpr::SimplExpr;
|
||||||
use crate::{
|
use crate::{
|
||||||
error::AstResult,
|
error::AstResult,
|
||||||
parser::{
|
parser::{
|
||||||
ast::{Ast, Span},
|
ast::Ast,
|
||||||
ast_iterator::AstIterator,
|
ast_iterator::AstIterator,
|
||||||
from_ast::{FromAst, FromAstElementContent},
|
from_ast::{FromAst, FromAstElementContent},
|
||||||
},
|
},
|
||||||
value::{AttrName, VarName},
|
|
||||||
};
|
};
|
||||||
|
use eww_shared_util::{AttrName, Span, VarName};
|
||||||
|
|
||||||
use super::widget_use::WidgetUse;
|
use super::widget_use::WidgetUse;
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, serde::Serialize)]
|
#[derive(Debug, PartialEq, Eq, Clone, serde::Serialize)]
|
||||||
|
|
|
@ -5,13 +5,9 @@ use simplexpr::SimplExpr;
|
||||||
use crate::{
|
use crate::{
|
||||||
config::attributes::AttrEntry,
|
config::attributes::AttrEntry,
|
||||||
error::AstResult,
|
error::AstResult,
|
||||||
parser::{
|
parser::{ast::Ast, ast_iterator::AstIterator, from_ast::FromAst},
|
||||||
ast::{Ast, Span},
|
|
||||||
ast_iterator::AstIterator,
|
|
||||||
from_ast::FromAst,
|
|
||||||
},
|
|
||||||
value::AttrName,
|
|
||||||
};
|
};
|
||||||
|
use eww_shared_util::{AttrName, Span, VarName};
|
||||||
|
|
||||||
use super::attributes::Attributes;
|
use super::attributes::Attributes;
|
||||||
|
|
||||||
|
@ -28,7 +24,7 @@ impl FromAst for WidgetUse {
|
||||||
let span = e.span();
|
let span = e.span();
|
||||||
if let Ok(text) = e.as_literal_ref() {
|
if let Ok(text) = e.as_literal_ref() {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
name: "text".to_string(),
|
name: "label".to_string(),
|
||||||
attrs: Attributes::new(
|
attrs: Attributes::new(
|
||||||
span.into(),
|
span.into(),
|
||||||
maplit::hashmap! {
|
maplit::hashmap! {
|
||||||
|
|
|
@ -5,12 +5,13 @@ use simplexpr::{dynval::DynVal, SimplExpr};
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{AstError, AstResult},
|
error::{AstError, AstResult},
|
||||||
parser::{
|
parser::{
|
||||||
ast::{Ast, Span},
|
ast::Ast,
|
||||||
ast_iterator::AstIterator,
|
ast_iterator::AstIterator,
|
||||||
from_ast::{FromAst, FromAstElementContent},
|
from_ast::{FromAst, FromAstElementContent},
|
||||||
},
|
},
|
||||||
value::{AttrName, NumWithUnit, VarName},
|
value::NumWithUnit,
|
||||||
};
|
};
|
||||||
|
use eww_shared_util::{AttrName, Span, VarName};
|
||||||
|
|
||||||
use super::{backend_window_options::BackendWindowOptions, widget_use::WidgetUse, window_geometry::WindowGeometry};
|
use super::{backend_window_options::BackendWindowOptions, widget_use::WidgetUse, window_geometry::WindowGeometry};
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,20 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
use simplexpr::{dynval::DynVal, SimplExpr};
|
use simplexpr::{dynval::DynVal, SimplExpr};
|
||||||
|
|
||||||
use crate::{enum_parse, error::{AstError, AstResult}, parser::{
|
use crate::{
|
||||||
ast::{Ast, Span}, ast_iterator::AstIterator,
|
enum_parse,
|
||||||
|
error::{AstError, AstResult},
|
||||||
|
parser::{
|
||||||
|
ast::Ast,
|
||||||
|
ast_iterator::AstIterator,
|
||||||
from_ast::{FromAst, FromAstElementContent},
|
from_ast::{FromAst, FromAstElementContent},
|
||||||
}, value::{AttrName, Coords, VarName}};
|
},
|
||||||
|
value::Coords,
|
||||||
|
};
|
||||||
|
|
||||||
use super::{widget_use::WidgetUse, window_definition::EnumParseError};
|
use super::{widget_use::WidgetUse, window_definition::EnumParseError};
|
||||||
use serde::{Serialize, Deserialize};
|
use eww_shared_util::{AttrName, Span, VarName};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, smart_default::SmartDefault, Serialize, Deserialize, strum::Display)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, smart_default::SmartDefault, Serialize, Deserialize, strum::Display)]
|
||||||
pub enum AnchorAlignment {
|
pub enum AnchorAlignment {
|
||||||
|
@ -84,7 +91,6 @@ pub enum AnchorPointParseError {
|
||||||
EnumParseError(#[from] EnumParseError),
|
EnumParseError(#[from] EnumParseError),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl std::str::FromStr for AnchorPoint {
|
impl std::str::FromStr for AnchorPoint {
|
||||||
type Err = AnchorPointParseError;
|
type Err = AnchorPointParseError;
|
||||||
|
|
||||||
|
@ -92,9 +98,7 @@ impl std::str::FromStr for AnchorPoint {
|
||||||
if s == "center" {
|
if s == "center" {
|
||||||
Ok(AnchorPoint { x: AnchorAlignment::CENTER, y: AnchorAlignment::CENTER })
|
Ok(AnchorPoint { x: AnchorAlignment::CENTER, y: AnchorAlignment::CENTER })
|
||||||
} else {
|
} else {
|
||||||
let (first, second) = s
|
let (first, second) = s.split_once(' ').ok_or_else(|| AnchorPointParseError::WrongFormat(s.to_string()))?;
|
||||||
.split_once(' ')
|
|
||||||
.ok_or_else(|| AnchorPointParseError::WrongFormat(s.to_string()))?;
|
|
||||||
let x_y_result: Result<_, EnumParseError> = try {
|
let x_y_result: Result<_, EnumParseError> = try {
|
||||||
AnchorPoint { x: AnchorAlignment::from_x_alignment(first)?, y: AnchorAlignment::from_y_alignment(second)? }
|
AnchorPoint { x: AnchorAlignment::from_x_alignment(first)?, y: AnchorAlignment::from_y_alignment(second)? }
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{attributes::AttrError, validate::ValidationError},
|
config::{attributes::AttrError, validate::ValidationError},
|
||||||
parser::{
|
parser::{
|
||||||
ast::{Ast, AstType, Span},
|
ast::{Ast, AstType},
|
||||||
lexer, parse_error,
|
lexer, parse_error,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use codespan_reporting::{diagnostic, files};
|
use codespan_reporting::{diagnostic, files};
|
||||||
|
use eww_shared_util::{AttrName, Span, VarName};
|
||||||
use simplexpr::dynval;
|
use simplexpr::dynval;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@ use diagnostic::*;
|
||||||
|
|
||||||
use crate::error::AstError;
|
use crate::error::AstError;
|
||||||
|
|
||||||
use super::parser::{ast::Span, parse_error};
|
use super::parser::parse_error;
|
||||||
|
use eww_shared_util::{AttrName, Span, VarName};
|
||||||
|
|
||||||
macro_rules! gen_diagnostic {
|
macro_rules! gen_diagnostic {
|
||||||
(
|
(
|
||||||
|
|
|
@ -2,61 +2,15 @@ use itertools::Itertools;
|
||||||
use simplexpr::{ast::SimplExpr, dynval::DynVal};
|
use simplexpr::{ast::SimplExpr, dynval::DynVal};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use eww_shared_util::Span;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
use super::{ast_iterator::AstIterator, from_ast::FromAst};
|
use super::{ast_iterator::AstIterator, from_ast::FromAst};
|
||||||
use crate::{
|
use crate::{
|
||||||
config::attributes::{AttrEntry, Attributes},
|
config::attributes::{AttrEntry, Attributes},
|
||||||
error::{AstError, AstResult, OptionAstErrorExt},
|
error::{AstError, AstResult, OptionAstErrorExt},
|
||||||
value::AttrName,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Clone, Copy, serde::Serialize)]
|
|
||||||
pub struct Span(pub usize, pub usize, pub usize);
|
|
||||||
|
|
||||||
impl Span {
|
|
||||||
/// Get the span that includes this and the other span completely.
|
|
||||||
/// Will panic if the spans are from different file_ids.
|
|
||||||
pub fn to(mut self, other: Span) -> Self {
|
|
||||||
assert!(other.2 == self.2);
|
|
||||||
self.1 = other.1;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ending_at(mut self, end: usize) -> Self {
|
|
||||||
self.1 = end;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn with_length(mut self, end: usize) -> Self {
|
|
||||||
self.1 = self.0;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<simplexpr::Span> for Span {
|
|
||||||
fn into(self) -> simplexpr::Span {
|
|
||||||
simplexpr::Span(self.0, self.1, self.2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl From<simplexpr::Span> for Span {
|
|
||||||
fn from(x: simplexpr::Span) -> Span {
|
|
||||||
Span(x.0, x.1, x.2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::fmt::Display for Span {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(f, "{}..{}", self.0, self.1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::fmt::Debug for Span {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(f, "{}..{}", self.0, self.1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
pub enum AstType {
|
pub enum AstType {
|
||||||
List,
|
List,
|
||||||
|
|
|
@ -5,14 +5,14 @@ use std::collections::HashMap;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
ast::{Ast, AstType, Span},
|
ast::{Ast, AstType},
|
||||||
from_ast::FromAst,
|
from_ast::FromAst,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
config::attributes::{AttrEntry, Attributes},
|
config::attributes::{AttrEntry, Attributes},
|
||||||
error::{AstError, AstResult, OptionAstErrorExt},
|
error::{AstError, AstResult, OptionAstErrorExt},
|
||||||
value::AttrName,
|
|
||||||
};
|
};
|
||||||
|
use eww_shared_util::{AttrName, Span, VarName};
|
||||||
|
|
||||||
pub struct AstIterator<I: Iterator<Item = Ast>> {
|
pub struct AstIterator<I: Iterator<Item = Ast>> {
|
||||||
remaining_span: Span,
|
remaining_span: Span,
|
||||||
|
@ -54,7 +54,7 @@ impl<I: Iterator<Item = Ast>> AstIterator<I> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expect_any<T: FromAst>(&mut self) -> AstResult<T> {
|
pub fn expect_any<T: FromAst>(&mut self) -> AstResult<T> {
|
||||||
self.iter.next().or_missing(self.remaining_span.with_length(0)).and_then(T::from_ast)
|
self.iter.next().or_missing(self.remaining_span.point_span()).and_then(T::from_ast)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expect_key_values(&mut self) -> AstResult<Attributes> {
|
pub fn expect_key_values(&mut self) -> AstResult<Attributes> {
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use super::{
|
use super::{
|
||||||
ast::{Ast, AstType, Span},
|
ast::{Ast, AstType},
|
||||||
ast_iterator::AstIterator,
|
ast_iterator::AstIterator,
|
||||||
};
|
};
|
||||||
use crate::{error::*, parser, util, value::AttrName};
|
use crate::{error::*, parser, util};
|
||||||
|
use eww_shared_util::{AttrName, Span, VarName};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use simplexpr::{ast::SimplExpr, dynval::DynVal};
|
use simplexpr::{ast::SimplExpr, dynval::DynVal};
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -49,7 +50,7 @@ impl<T: FromAstElementContent> FromAst for T {
|
||||||
impl FromAst for SimplExpr {
|
impl FromAst for SimplExpr {
|
||||||
fn from_ast(e: Ast) -> AstResult<Self> {
|
fn from_ast(e: Ast) -> AstResult<Self> {
|
||||||
match e {
|
match e {
|
||||||
Ast::Symbol(span, x) => Ok(SimplExpr::VarRef(span.into(), x)),
|
Ast::Symbol(span, x) => Ok(SimplExpr::VarRef(span.into(), VarName(x))),
|
||||||
Ast::Literal(span, x) => Ok(SimplExpr::Literal(span.into(), x)),
|
Ast::Literal(span, x) => Ok(SimplExpr::Literal(span.into(), x)),
|
||||||
Ast::SimplExpr(span, x) => Ok(x),
|
Ast::SimplExpr(span, x) => Ok(x),
|
||||||
_ => Err(AstError::NotAValue(e.span(), e.expr_type())),
|
_ => Err(AstError::NotAValue(e.span(), e.expr_type())),
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use regex::{Regex, RegexSet};
|
use regex::{Regex, RegexSet};
|
||||||
|
|
||||||
use super::{ast::Span, parse_error};
|
use super::parse_error;
|
||||||
|
use eww_shared_util::{AttrName, Span, VarName};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub enum Token {
|
pub enum Token {
|
||||||
|
|
|
@ -25,6 +25,13 @@ pub fn parse_string(file_id: usize, s: &str) -> AstResult<Ast> {
|
||||||
parser.parse(file_id, lexer).map_err(|e| AstError::from_parse_error(file_id, e))
|
parser.parse(file_id, lexer).map_err(|e| AstError::from_parse_error(file_id, e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parse multiple toplevel nodes into an [Ast::List]
|
||||||
|
pub fn parse_toplevel(file_id: usize, s: &str) -> AstResult<Ast> {
|
||||||
|
let lexer = lexer::Lexer::new(file_id, s.to_string());
|
||||||
|
let parser = parser::ToplevelParser::new();
|
||||||
|
parser.parse(file_id, lexer).map(|(span, nodes)| Ast::List(span, nodes)).map_err(|e| AstError::from_parse_error(file_id, e))
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! test_parser {
|
macro_rules! test_parser {
|
||||||
($($text:literal),*) => {{
|
($($text:literal),*) => {{
|
||||||
let p = parser::AstParser::new();
|
let p = parser::AstParser::new();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use super::ast::Span;
|
use eww_shared_util::{AttrName, Span, VarName};
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum ParseError {
|
pub enum ParseError {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use crate::parser::{lexer::{Token}, ast::{Ast, Span}, parse_error};
|
use crate::parser::{lexer::Token, ast::Ast, parse_error};
|
||||||
|
use eww_shared_util::Span;
|
||||||
use simplexpr::ast::SimplExpr;
|
use simplexpr::ast::SimplExpr;
|
||||||
use simplexpr;
|
use simplexpr;
|
||||||
use lalrpop_util::ParseError;
|
use lalrpop_util::ParseError;
|
||||||
|
@ -59,7 +60,7 @@ SimplExpr: SimplExpr = {
|
||||||
<l:@L> <x:"simplexpr"> =>? {
|
<l:@L> <x:"simplexpr"> =>? {
|
||||||
let expr = x[1..x.len() - 1].to_string();
|
let expr = x[1..x.len() - 1].to_string();
|
||||||
simplexpr::parse_string(file_id, &expr).map_err(|e| {
|
simplexpr::parse_string(file_id, &expr).map_err(|e| {
|
||||||
let span = e.get_span().map(|simplexpr::Span(simpl_l, simpl_r, file_id)| Span(1 + l + simpl_l, 1 + l + simpl_r, file_id));
|
let span = e.get_span().map(|Span(simpl_l, simpl_r, file_id)| Span(1 + l + simpl_l, 1 + l + simpl_r, file_id));
|
||||||
ParseError::User { error: parse_error::ParseError::SimplExpr(span, e) }})
|
ParseError::User { error: parse_error::ParseError::SimplExpr(span, e) }})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,39 +3,3 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub mod coords;
|
pub mod coords;
|
||||||
pub use coords::*;
|
pub use coords::*;
|
||||||
|
|
||||||
/// The name of a variable
|
|
||||||
#[repr(transparent)]
|
|
||||||
#[derive(Clone, Hash, PartialEq, Eq, Serialize, Deserialize, AsRef, From, FromStr, Display, DebugCustom)]
|
|
||||||
#[debug(fmt = "VarName({})", .0)]
|
|
||||||
pub struct VarName(pub String);
|
|
||||||
|
|
||||||
impl std::borrow::Borrow<str> for VarName {
|
|
||||||
fn borrow(&self) -> &str {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&str> for VarName {
|
|
||||||
fn from(s: &str) -> Self {
|
|
||||||
VarName(s.to_owned())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The name of an attribute
|
|
||||||
#[repr(transparent)]
|
|
||||||
#[derive(Clone, Hash, PartialEq, Eq, Serialize, Deserialize, AsRef, From, FromStr, Display, DebugCustom)]
|
|
||||||
#[debug(fmt="AttrName({})", .0)]
|
|
||||||
pub struct AttrName(pub String);
|
|
||||||
|
|
||||||
impl std::borrow::Borrow<str> for AttrName {
|
|
||||||
fn borrow(&self) -> &str {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&str> for AttrName {
|
|
||||||
fn from(s: &str) -> Self {
|
|
||||||
AttrName(s.to_owned())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue