35 Commits

Author SHA1 Message Date
Tom Alexander
36b80dc093 Separate out rust parsing step to support references to values stored in the parsed state.
Some checks failed
clippy Build clippy has failed
rust-foreign-document-test Build rust-foreign-document-test has succeeded
rust-build Build rust-build has succeeded
rust-test Build rust-test has succeeded
2023-12-27 12:24:21 -05:00
Tom Alexander
1812b1a56e Remove phantom data. 2023-12-27 12:24:21 -05:00
Tom Alexander
1a70b3d2c0 Add a lifetime for data in the parsed result but not from the source. 2023-12-27 12:24:21 -05:00
Tom Alexander
abf066701e Add category and path to WasmDocument. 2023-12-27 11:31:35 -05:00
Tom Alexander
4984ea4179 More of the test structure. 2023-12-27 11:10:40 -05:00
Tom Alexander
3cb251ea6c Move terminal colors to the shared util module. 2023-12-27 10:57:40 -05:00
Tom Alexander
4bfea41291 Add more structure to the wasm compare. 2023-12-27 10:52:59 -05:00
Tom Alexander
99376515ef Invoking wasm_compare_document.
Some checks failed
clippy Build clippy has failed
rust-foreign-document-test Build rust-foreign-document-test has succeeded
rust-build Build rust-build has succeeded
rust-test Build rust-test has succeeded
2023-12-27 09:31:54 -05:00
Tom Alexander
23f4ba4205 Serialize to wasm during wasm compare.
Some checks failed
clippy Build clippy has failed
rust-foreign-document-test Build rust-foreign-document-test has succeeded
rust-build Build rust-build has failed
rust-test Build rust-test has succeeded
2023-12-27 08:57:56 -05:00
Tom Alexander
55ad136283 Fix imports for wasm. 2023-12-27 08:49:34 -05:00
Tom Alexander
c717541099 Move the parsing of the elisp to the util module. 2023-12-27 08:46:18 -05:00
Tom Alexander
c2e921c2dc Move wasm test to a top-level module.
For some unknown reason, this makes rust-analyzer not angry.
2023-12-27 08:42:13 -05:00
Tom Alexander
e499169f0e Fix imports for wasm_test.
Some checks failed
clippy Build clippy has failed
rust-build Build rust-build has failed
rust-foreign-document-test Build rust-foreign-document-test has succeeded
rust-test Build rust-test has succeeded
2023-12-27 08:37:34 -05:00
Tom Alexander
84c088df67 Add wasm targets to the build test in the CI.
Some checks failed
clippy Build clippy has failed
rust-foreign-document-test Build rust-foreign-document-test has succeeded
rust-build Build rust-build has succeeded
rust-test Build rust-test has succeeded
2023-12-27 08:04:03 -05:00
Tom Alexander
f210f95f99 Use a temporary folder for the builds. 2023-12-26 21:23:20 -05:00
Tom Alexander
17b81c7c72 Add a script to build every possible feature combination. 2023-12-26 21:05:40 -05:00
Tom Alexander
2911fce7cc Put util under the library. 2023-12-26 20:18:41 -05:00
Tom Alexander
e622d9fa6b Remove the old implementation of print_versions.
Some checks failed
clippy Build clippy has failed
rust-foreign-document-test Build rust-foreign-document-test has succeeded
rust-build Build rust-build has succeeded
rust-test Build rust-test has succeeded
2023-12-26 19:15:02 -05:00
Tom Alexander
8186fbb8b3 Move print_versions into a util crate. 2023-12-26 19:06:12 -05:00
Tom Alexander
68ccff74fa Outline for the wasm compare function. 2023-12-26 18:55:28 -05:00
Tom Alexander
9a13cb72c6 Make the wasm test binary async. 2023-12-25 14:32:01 -05:00
Tom Alexander
65abaa332f Separate out the wasm test into its own feature/binary. 2023-12-25 13:12:32 -05:00
Tom Alexander
67e5829fd9 Populating document's children. 2023-12-25 12:55:48 -05:00
Tom Alexander
995b41e697 Remove deserialize to support borrows. 2023-12-25 12:42:38 -05:00
Tom Alexander
eb51bdfe2f Add original field name to wasm macro. 2023-12-25 12:32:35 -05:00
Tom Alexander
bbb9ec637a Add code to test the wasm code path without actually dropping into wasm. 2023-12-25 12:14:50 -05:00
Tom Alexander
dc012b49f5 Add a generic WasmAstNode enum. 2023-12-25 11:51:39 -05:00
Tom Alexander
13863a68f7 Add placeholders for all the wasm ast nodes. 2023-12-25 11:33:43 -05:00
Tom Alexander
2962f76c81 Add lifetime to wasm objects. 2023-12-25 11:19:09 -05:00
Tom Alexander
b9b3ef6e74 Populate standard properties. 2023-12-25 10:47:10 -05:00
Tom Alexander
310ab2eab2 Add standard properties to wasm. 2023-12-24 15:26:45 -05:00
Tom Alexander
53320070da Define a wasm document. 2023-12-24 15:17:41 -05:00
Tom Alexander
2d5593681f Start defining the return type. 2023-12-24 13:02:34 -05:00
Tom Alexander
b3f97dbb40 Add wasm-bindgen. 2023-12-24 00:59:41 -05:00
Tom Alexander
a48d76321e Building basic wasm. 2023-12-24 00:47:32 -05:00
80 changed files with 2757 additions and 121 deletions

View File

@@ -192,6 +192,54 @@ spec:
] ]
- name: docker-image - name: docker-image
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)" value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
- name: run-image-wasm
taskRef:
name: run-docker-image
workspaces:
- name: source
workspace: git-source
- name: cargo-cache
workspace: cargo-cache
runAfter:
- run-image-all
params:
- name: args
value:
[
"--target",
"wasm32-unknown-unknown",
"--profile",
"wasm",
"--bin",
"wasm",
"--no-default-features",
"--features",
"wasm",
]
- name: docker-image
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
- name: run-image-wasm-test
taskRef:
name: run-docker-image
workspaces:
- name: source
workspace: git-source
- name: cargo-cache
workspace: cargo-cache
runAfter:
- run-image-wasm
params:
- name: args
value:
[
"--bin",
"wasm_test",
"--no-default-features",
"--features",
"wasm_test",
]
- name: docker-image
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
finally: finally:
- name: report-success - name: report-success
when: when:

View File

@@ -39,17 +39,31 @@ path = "src/lib.rs"
path = "src/bin_foreign_document_test.rs" path = "src/bin_foreign_document_test.rs"
required-features = ["foreign_document_test"] required-features = ["foreign_document_test"]
[[bin]]
name = "wasm"
path = "src/bin_wasm.rs"
required-features = ["wasm"]
[[bin]]
name = "wasm_test"
path = "src/bin_wasm_test.rs"
required-features = ["wasm_test"]
[dependencies] [dependencies]
futures = { version = "0.3.28", optional = true } futures = { version = "0.3.28", optional = true }
nom = "7.1.1" nom = "7.1.1"
opentelemetry = { version = "0.20.0", optional = true, default-features = false, features = ["trace", "rt-tokio"] } opentelemetry = { version = "0.20.0", optional = true, default-features = false, features = ["trace", "rt-tokio"] }
opentelemetry-otlp = { version = "0.13.0", optional = true } opentelemetry-otlp = { version = "0.13.0", optional = true }
opentelemetry-semantic-conventions = { version = "0.12.0", optional = true } opentelemetry-semantic-conventions = { version = "0.12.0", optional = true }
serde = { version = "1.0.193", optional = true, features = ["derive"] }
serde-wasm-bindgen = { version = "0.6.3", optional = true }
serde_json = { version = "1.0.108", optional = true }
tokio = { version = "1.30.0", optional = true, default-features = false, features = ["rt", "rt-multi-thread"] } tokio = { version = "1.30.0", optional = true, default-features = false, features = ["rt", "rt-multi-thread"] }
tracing = { version = "0.1.37", optional = true } tracing = { version = "0.1.37", optional = true }
tracing-opentelemetry = { version = "0.20.0", optional = true } tracing-opentelemetry = { version = "0.20.0", optional = true }
tracing-subscriber = { version = "0.3.17", optional = true, features = ["env-filter"] } tracing-subscriber = { version = "0.3.17", optional = true, features = ["env-filter"] }
walkdir = { version = "2.3.3", optional = true } walkdir = { version = "2.3.3", optional = true }
wasm-bindgen = { version = "0.2.89", optional = true }
[build-dependencies] [build-dependencies]
walkdir = "2.3.3" walkdir = "2.3.3"
@@ -60,6 +74,8 @@ compare = ["tokio/process", "tokio/macros"]
foreign_document_test = ["compare", "dep:futures", "tokio/sync", "dep:walkdir", "tokio/process"] foreign_document_test = ["compare", "dep:futures", "tokio/sync", "dep:walkdir", "tokio/process"]
tracing = ["dep:opentelemetry", "dep:opentelemetry-otlp", "dep:opentelemetry-semantic-conventions", "dep:tokio", "dep:tracing", "dep:tracing-opentelemetry", "dep:tracing-subscriber"] tracing = ["dep:opentelemetry", "dep:opentelemetry-otlp", "dep:opentelemetry-semantic-conventions", "dep:tokio", "dep:tracing", "dep:tracing-opentelemetry", "dep:tracing-subscriber"]
event_count = [] event_count = []
wasm = ["dep:serde", "dep:wasm-bindgen", "dep:serde-wasm-bindgen"]
wasm_test = ["wasm", "dep:serde_json", "tokio/process", "tokio/macros"]
# Optimized build for any sort of release. # Optimized build for any sort of release.
[profile.release-lto] [profile.release-lto]
@@ -79,3 +95,8 @@ strip = "symbols"
inherits = "release" inherits = "release"
lto = true lto = true
debug = true debug = true
[profile.wasm]
inherits = "release"
lto = true
strip = true

View File

@@ -29,6 +29,15 @@ build:
release: release:
> cargo build --release $(RELEASEFLAGS) > cargo build --release $(RELEASEFLAGS)
.PHONY: wasm
wasm:
> cargo build --target=wasm32-unknown-unknown --profile wasm --bin wasm --features wasm
> wasm-bindgen --target web --out-dir target/wasm32-unknown-unknown/js target/wasm32-unknown-unknown/wasm/wasm.wasm
.PHONY: run_wasm
run_wasm:
> cat /tmp/test.org | cargo run --profile wasm --bin wasm_test --features wasm_test
.PHONY: clean .PHONY: clean
clean: clean:
> cargo clean > cargo clean

View File

@@ -2,5 +2,6 @@ FROM rustlang/rust:nightly-alpine3.17
RUN apk add --no-cache musl-dev RUN apk add --no-cache musl-dev
RUN cargo install --locked --no-default-features --features ci-autoclean cargo-cache RUN cargo install --locked --no-default-features --features ci-autoclean cargo-cache
RUN rustup target add wasm32-unknown-unknown
ENTRYPOINT ["cargo", "build"] ENTRYPOINT ["cargo", "build"]

View File

@@ -0,0 +1,76 @@
#!/usr/bin/env bash
#
# Time running a single parse without invoking a compare with emacs.
set -euo pipefail
IFS=$'\n\t'
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
: ${PROFILE:="debug"}
############## Setup #########################
function cleanup {
for f in "${folders[@]}"; do
log "Deleting $f"
rm -rf "$f"
done
}
folders=()
for sig in EXIT INT QUIT HUP TERM; do
trap "set +e; cleanup" "$sig"
done
function die {
local status_code="$1"
shift
(>&2 echo "${@}")
exit "$status_code"
}
function log {
(>&2 echo "${@}")
}
############## Program #########################
function main {
if [ "$#" -gt 0 ]; then
export CARGO_TARGET_DIR="$1"
else
local work_directory=$(mktemp -d -t 'organic.XXXXXX')
folders+=("$work_directory")
export CARGO_TARGET_DIR="$work_directory"
fi
local features=(compare foreign_document_test tracing event_count wasm wasm_test)
ENABLED_FEATURES= for_each_combination "${features[@]}"
}
function for_each_combination {
local additional_flags=()
if [ "$PROFILE" = "dev" ] || [ "$PROFILE" = "debug" ]; then
PROFILE="debug"
else
additional_flags+=(--profile "$PROFILE")
fi
local flag=$1
shift
if [ "$#" -gt 0 ]; then
ENABLED_FEATURES="$ENABLED_FEATURES" for_each_combination "${@}"
elif [ -z "$ENABLED_FEATURES" ]; then
(cd "$DIR/../" && printf "\n\n\n========== no features ==========\n\n\n" && set -x && cargo build "${additional_flags[@]}" --no-default-features)
else
(cd "$DIR/../" && printf "\n\n\n========== %s ==========\n\n\n" "${ENABLED_FEATURES:1}" && set -x && cargo build "${additional_flags[@]}" --no-default-features --features "${ENABLED_FEATURES:1}")
fi
ENABLED_FEATURES="$ENABLED_FEATURES,$flag"
if [ "$#" -gt 0 ]; then
ENABLED_FEATURES="$ENABLED_FEATURES" for_each_combination "${@}"
else
(cd "$DIR/../" && printf "\n\n\n========== %s ==========\n\n\n" "${ENABLED_FEATURES:1}" && set -x && cargo build "${additional_flags[@]}" --no-default-features --features "${ENABLED_FEATURES:1}")
fi
}
main "${@}"

View File

@@ -1,3 +1,4 @@
#![feature(exit_status_error)]
#![feature(round_char_boundary)] #![feature(round_char_boundary)]
#![feature(exact_size_is_empty)] #![feature(exact_size_is_empty)]
use std::io::Read; use std::io::Read;

30
src/bin_wasm.rs Normal file
View File

@@ -0,0 +1,30 @@
use organic::parser::parse_with_settings;
use organic::settings::GlobalSettings;
use organic::wasm::ParseResult;
use organic::wasm::ToWasm;
use organic::wasm::ToWasmContext;
use wasm_bindgen::prelude::wasm_bindgen;
#[wasm_bindgen]
pub fn parse_org(org_contents: &str) -> wasm_bindgen::JsValue {
let rust_parsed = match parse_with_settings(org_contents, &GlobalSettings::default()) {
Ok(document) => document,
Err(err) => {
return serde_wasm_bindgen::to_value(&ParseResult::Error(format!("{:?}", err)))
.unwrap();
}
};
let to_wasm_context = ToWasmContext::new(org_contents);
let wasm_document = match rust_parsed.to_wasm(to_wasm_context) {
Ok(document) => document,
Err(err) => {
return serde_wasm_bindgen::to_value(&ParseResult::Error(format!("{:?}", err)))
.unwrap();
}
};
serde_wasm_bindgen::to_value(&ParseResult::Success(wasm_document)).unwrap()
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}

62
src/bin_wasm_test.rs Normal file
View File

@@ -0,0 +1,62 @@
#![feature(exact_size_is_empty)]
#![feature(exit_status_error)]
use std::io::Read;
use organic::wasm_test::wasm_run_anonymous_compare;
#[cfg(feature = "tracing")]
use crate::init_tracing::init_telemetry;
#[cfg(feature = "tracing")]
use crate::init_tracing::shutdown_telemetry;
#[cfg(feature = "tracing")]
mod init_tracing;
#[cfg(not(feature = "tracing"))]
fn main() -> Result<(), Box<dyn std::error::Error>> {
let rt = tokio::runtime::Runtime::new()?;
rt.block_on(async {
let main_body_result = main_body().await;
main_body_result
})
}
#[cfg(feature = "tracing")]
fn main() -> Result<(), Box<dyn std::error::Error>> {
let rt = tokio::runtime::Runtime::new()?;
rt.block_on(async {
init_telemetry()?;
let main_body_result = main_body().await;
shutdown_telemetry()?;
main_body_result
})
}
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
async fn main_body() -> Result<(), Box<dyn std::error::Error>> {
let args = std::env::args().skip(1);
if args.is_empty() {
let org_contents = read_stdin_to_string()?;
if wasm_run_anonymous_compare(org_contents).await? {
} else {
Err("Diff results do not match.")?;
}
Ok(())
} else {
todo!()
// for arg in args {
// if run_compare_on_file(arg).await? {
// } else {
// Err("Diff results do not match.")?;
// }
// }
// Ok(())
}
}
fn read_stdin_to_string() -> Result<String, Box<dyn std::error::Error>> {
let mut stdin_contents = String::new();
std::io::stdin()
.lock()
.read_to_string(&mut stdin_contents)?;
Ok(stdin_contents)
}

View File

@@ -2,15 +2,16 @@ use std::path::Path;
use crate::compare::diff::compare_document; use crate::compare::diff::compare_document;
use crate::compare::diff::DiffResult; use crate::compare::diff::DiffResult;
use crate::compare::parse::emacs_parse_anonymous_org_document;
use crate::compare::parse::emacs_parse_file_org_document;
use crate::compare::parse::get_emacs_version;
use crate::compare::parse::get_org_mode_version;
use crate::compare::sexp::sexp; use crate::compare::sexp::sexp;
use crate::context::GlobalSettings; use crate::context::GlobalSettings;
use crate::context::LocalFileAccessInterface; use crate::context::LocalFileAccessInterface;
use crate::parser::parse_file_with_settings; use crate::parser::parse_file_with_settings;
use crate::parser::parse_with_settings; use crate::parser::parse_with_settings;
use crate::util::emacs_parse_anonymous_org_document;
use crate::util::emacs_parse_file_org_document;
use crate::util::foreground_color;
use crate::util::print_versions;
use crate::util::reset_color;
pub async fn run_anonymous_compare<P: AsRef<str>>( pub async fn run_anonymous_compare<P: AsRef<str>>(
org_contents: P, org_contents: P,
@@ -68,8 +69,8 @@ pub async fn run_anonymous_compare_with_settings<'g, 's, P: AsRef<str>>(
} else if !silent { } else if !silent {
println!( println!(
"{color}Entire document passes.{reset}", "{color}Entire document passes.{reset}",
color = DiffResult::foreground_color(0, 255, 0), color = foreground_color(0, 255, 0),
reset = DiffResult::reset_color(), reset = reset_color(),
); );
} }
@@ -121,19 +122,10 @@ pub async fn run_compare_on_file_with_settings<'g, 's, P: AsRef<Path>>(
} else if !silent { } else if !silent {
println!( println!(
"{color}Entire document passes.{reset}", "{color}Entire document passes.{reset}",
color = DiffResult::foreground_color(0, 255, 0), color = foreground_color(0, 255, 0),
reset = DiffResult::reset_color(), reset = reset_color(),
); );
} }
Ok(true) Ok(true)
} }
async fn print_versions() -> Result<(), Box<dyn std::error::Error>> {
eprintln!("Using emacs version: {}", get_emacs_version().await?.trim());
eprintln!(
"Using org-mode version: {}",
get_org_mode_version().await?.trim()
);
Ok(())
}

View File

@@ -109,6 +109,8 @@ use crate::types::Verbatim;
use crate::types::VerseBlock; use crate::types::VerseBlock;
use crate::types::WarningDelayType; use crate::types::WarningDelayType;
use crate::types::Year; use crate::types::Year;
use crate::util::foreground_color;
use crate::util::reset_color;
#[derive(Debug)] #[derive(Debug)]
pub enum DiffEntry<'b, 's> { pub enum DiffEntry<'b, 's> {
@@ -200,21 +202,21 @@ impl<'b, 's> DiffResult<'b, 's> {
if self.has_bad_children() { if self.has_bad_children() {
format!( format!(
"{color}BADCHILD{reset}", "{color}BADCHILD{reset}",
color = DiffResult::foreground_color(255, 255, 0), color = foreground_color(255, 255, 0),
reset = DiffResult::reset_color(), reset = reset_color(),
) )
} else { } else {
format!( format!(
"{color}GOOD{reset}", "{color}GOOD{reset}",
color = DiffResult::foreground_color(0, 255, 0), color = foreground_color(0, 255, 0),
reset = DiffResult::reset_color(), reset = reset_color(),
) )
} }
} }
DiffStatus::Bad => format!( DiffStatus::Bad => format!(
"{color}BAD{reset}", "{color}BAD{reset}",
color = DiffResult::foreground_color(255, 0, 0), color = foreground_color(255, 0, 0),
reset = DiffResult::reset_color(), reset = reset_color(),
), ),
} }
}; };
@@ -239,45 +241,6 @@ impl<'b, 's> DiffResult<'b, 's> {
.iter() .iter()
.any(|child| child.is_immediately_bad() || child.has_bad_children()) .any(|child| child.is_immediately_bad() || child.has_bad_children())
} }
pub(crate) fn foreground_color(red: u8, green: u8, blue: u8) -> String {
if DiffResult::should_use_color() {
format!(
"\x1b[38;2;{red};{green};{blue}m",
red = red,
green = green,
blue = blue
)
} else {
String::new()
}
}
#[allow(dead_code)]
pub(crate) fn background_color(red: u8, green: u8, blue: u8) -> String {
if DiffResult::should_use_color() {
format!(
"\x1b[48;2;{red};{green};{blue}m",
red = red,
green = green,
blue = blue
)
} else {
String::new()
}
}
pub(crate) fn reset_color() -> &'static str {
if DiffResult::should_use_color() {
"\x1b[0m"
} else {
""
}
}
fn should_use_color() -> bool {
!std::env::var("NO_COLOR").is_ok_and(|val| !val.is_empty())
}
} }
impl<'b, 's> DiffLayer<'b, 's> { impl<'b, 's> DiffLayer<'b, 's> {
@@ -295,14 +258,14 @@ impl<'b, 's> DiffLayer<'b, 's> {
let status_text = if self.has_bad_children() { let status_text = if self.has_bad_children() {
format!( format!(
"{color}BADCHILD{reset}", "{color}BADCHILD{reset}",
color = DiffResult::foreground_color(255, 255, 0), color = foreground_color(255, 255, 0),
reset = DiffResult::reset_color(), reset = reset_color(),
) )
} else { } else {
format!( format!(
"{color}GOOD{reset}", "{color}GOOD{reset}",
color = DiffResult::foreground_color(0, 255, 0), color = foreground_color(0, 255, 0),
reset = DiffResult::reset_color(), reset = reset_color(),
) )
}; };
println!( println!(

View File

@@ -4,7 +4,6 @@ mod compare_field;
mod diff; mod diff;
mod elisp_fact; mod elisp_fact;
mod macros; mod macros;
mod parse;
mod sexp; mod sexp;
mod util; mod util;
pub use compare::run_anonymous_compare; pub use compare::run_anonymous_compare;
@@ -13,3 +12,5 @@ pub use compare::run_compare_on_file;
pub use compare::run_compare_on_file_with_settings; pub use compare::run_compare_on_file_with_settings;
pub use compare::silent_anonymous_compare; pub use compare::silent_anonymous_compare;
pub use compare::silent_compare_on_file; pub use compare::silent_compare_on_file;
pub use sexp::sexp;
pub use sexp::Token;

View File

@@ -8,8 +8,15 @@
extern crate test; extern crate test;
#[cfg(feature = "compare")] // TODO: I only include compare to use some shared stuff like sexp and DiffResult. Ideally, this would be moved to a shared module.
#[cfg(any(feature = "compare", feature = "wasm_test"))]
pub mod compare; pub mod compare;
#[cfg(any(feature = "compare", feature = "wasm_test"))]
pub mod util;
#[cfg(any(feature = "wasm", feature = "wasm_test"))]
pub mod wasm;
#[cfg(feature = "wasm_test")]
pub mod wasm_test;
mod context; mod context;
mod error; mod error;

View File

@@ -1,29 +1,55 @@
use std::borrow::Cow;
use std::path::Path; use std::path::Path;
use tokio::process::Command; use tokio::process::Command;
use crate::context::HeadlineLevelFilter;
use crate::settings::GlobalSettings; use crate::settings::GlobalSettings;
use crate::settings::HeadlineLevelFilter;
/// Generate elisp to configure org-mode parsing settings pub async fn print_versions() -> Result<(), Box<dyn std::error::Error>> {
/// eprintln!("Using emacs version: {}", get_emacs_version().await?.trim());
/// Currently only org-list-allow-alphabetical is supported. eprintln!(
fn global_settings_elisp(global_settings: &GlobalSettings) -> String { "Using org-mode version: {}",
// This string concatenation is wildly inefficient but its only called in tests 🤷. get_org_mode_version().await?.trim()
let mut ret = "".to_owned(); );
if global_settings.list_allow_alphabetical { Ok(())
ret += "(setq org-list-allow-alphabetical t)\n"
} }
if global_settings.tab_width != crate::settings::DEFAULT_TAB_WIDTH {
ret += format!("(setq-default tab-width {})", global_settings.tab_width).as_str(); pub(crate) async fn get_emacs_version() -> Result<String, Box<dyn std::error::Error>> {
let elisp_script = r#"(progn
(message "%s" (version))
)"#;
let mut cmd = Command::new("emacs");
let cmd = cmd
.arg("-q")
.arg("--no-site-file")
.arg("--no-splash")
.arg("--batch")
.arg("--eval")
.arg(elisp_script);
let out = cmd.output().await?;
out.status.exit_ok()?;
Ok(String::from_utf8(out.stderr)?)
} }
if global_settings.odd_levels_only != HeadlineLevelFilter::default() {
ret += match global_settings.odd_levels_only { pub(crate) async fn get_org_mode_version() -> Result<String, Box<dyn std::error::Error>> {
HeadlineLevelFilter::Odd => "(setq org-odd-levels-only t)\n", let elisp_script = r#"(progn
HeadlineLevelFilter::OddEven => "(setq org-odd-levels-only nil)\n", (org-mode)
}; (message "%s" (org-version nil t nil))
} )"#;
ret let mut cmd = Command::new("emacs");
let cmd = cmd
.arg("-q")
.arg("--no-site-file")
.arg("--no-splash")
.arg("--batch")
.arg("--eval")
.arg(elisp_script);
let out = cmd.output().await?;
out.status.exit_ok()?;
Ok(String::from_utf8(out.stderr)?)
} }
pub(crate) async fn emacs_parse_anonymous_org_document<'g, 's, C>( pub(crate) async fn emacs_parse_anonymous_org_document<'g, 's, C>(
@@ -144,39 +170,64 @@ where
output output
} }
pub async fn get_emacs_version() -> Result<String, Box<dyn std::error::Error>> { /// Generate elisp to configure org-mode parsing settings
let elisp_script = r#"(progn ///
(message "%s" (version)) /// Currently only org-list-allow-alphabetical is supported.
)"#; fn global_settings_elisp(global_settings: &GlobalSettings) -> String {
let mut cmd = Command::new("emacs"); // This string concatenation is wildly inefficient but its only called in tests 🤷.
let cmd = cmd let mut ret = "".to_owned();
.arg("-q") if global_settings.list_allow_alphabetical {
.arg("--no-site-file") ret += "(setq org-list-allow-alphabetical t)\n"
.arg("--no-splash") }
.arg("--batch") if global_settings.tab_width != crate::settings::DEFAULT_TAB_WIDTH {
.arg("--eval") ret += format!("(setq-default tab-width {})", global_settings.tab_width).as_str();
.arg(elisp_script); }
if global_settings.odd_levels_only != HeadlineLevelFilter::default() {
let out = cmd.output().await?; ret += match global_settings.odd_levels_only {
out.status.exit_ok()?; HeadlineLevelFilter::Odd => "(setq org-odd-levels-only t)\n",
Ok(String::from_utf8(out.stderr)?) HeadlineLevelFilter::OddEven => "(setq org-odd-levels-only nil)\n",
};
}
ret
} }
pub async fn get_org_mode_version() -> Result<String, Box<dyn std::error::Error>> { fn should_use_color() -> bool {
let elisp_script = r#"(progn !std::env::var("NO_COLOR").is_ok_and(|val| !val.is_empty())
(org-mode) }
(message "%s" (org-version nil t nil))
)"#; pub(crate) fn foreground_color(red: u8, green: u8, blue: u8) -> Cow<'static, str> {
let mut cmd = Command::new("emacs"); if should_use_color() {
let cmd = cmd format!(
.arg("-q") "\x1b[38;2;{red};{green};{blue}m",
.arg("--no-site-file") red = red,
.arg("--no-splash") green = green,
.arg("--batch") blue = blue
.arg("--eval") )
.arg(elisp_script); .into()
} else {
let out = cmd.output().await?; Cow::from("")
out.status.exit_ok()?; }
Ok(String::from_utf8(out.stderr)?) }
#[allow(dead_code)]
pub(crate) fn background_color(red: u8, green: u8, blue: u8) -> Cow<'static, str> {
if should_use_color() {
format!(
"\x1b[48;2;{red};{green};{blue}m",
red = red,
green = green,
blue = blue
)
.into()
} else {
Cow::from("")
}
}
pub(crate) fn reset_color() -> &'static str {
if should_use_color() {
"\x1b[0m"
} else {
""
}
} }

30
src/wasm/angle_link.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::AngleLink;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmAngleLink<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmAngleLink<'s, 'p>,
AngleLink<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmAngleLink {
standard_properties,
children: Vec::new(),
})
}
);

128
src/wasm/ast_node.rs Normal file
View File

@@ -0,0 +1,128 @@
use serde::Serialize;
use super::angle_link::WasmAngleLink;
use super::babel_call::WasmBabelCall;
use super::bold::WasmBold;
use super::center_block::WasmCenterBlock;
use super::citation::WasmCitation;
use super::citation_reference::WasmCitationReference;
use super::clock::WasmClock;
use super::code::WasmCode;
use super::comment::WasmComment;
use super::comment_block::WasmCommentBlock;
use super::diary_sexp::WasmDiarySexp;
use super::document::WasmDocument;
use super::drawer::WasmDrawer;
use super::dynamic_block::WasmDynamicBlock;
use super::entity::WasmEntity;
use super::example_block::WasmExampleBlock;
use super::export_block::WasmExportBlock;
use super::export_snippet::WasmExportSnippet;
use super::fixed_width_area::WasmFixedWidthArea;
use super::footnote_definition::WasmFootnoteDefinition;
use super::footnote_reference::WasmFootnoteReference;
use super::headline::WasmHeadline;
use super::horizontal_rule::WasmHorizontalRule;
use super::inline_babel_call::WasmInlineBabelCall;
use super::inline_source_block::WasmInlineSourceBlock;
use super::italic::WasmItalic;
use super::keyword::WasmKeyword;
use super::latex_environment::WasmLatexEnvironment;
use super::latex_fragment::WasmLatexFragment;
use super::line_break::WasmLineBreak;
use super::node_property::WasmNodeProperty;
use super::org_macro::WasmOrgMacro;
use super::paragraph::WasmParagraph;
use super::plain_link::WasmPlainLink;
use super::plain_list::WasmPlainList;
use super::plain_list_item::WasmPlainListItem;
use super::plain_text::WasmPlainText;
use super::planning::WasmPlanning;
use super::property_drawer::WasmPropertyDrawer;
use super::quote_block::WasmQuoteBlock;
use super::radio_link::WasmRadioLink;
use super::radio_target::WasmRadioTarget;
use super::regular_link::WasmRegularLink;
use super::section::WasmSection;
use super::special_block::WasmSpecialBlock;
use super::src_block::WasmSrcBlock;
use super::statistics_cookie::WasmStatisticsCookie;
use super::strike_through::WasmStrikeThrough;
use super::subscript::WasmSubscript;
use super::superscript::WasmSuperscript;
use super::table::WasmTable;
use super::table_cell::WasmTableCell;
use super::table_row::WasmTableRow;
use super::target::WasmTarget;
use super::timestamp::WasmTimestamp;
use super::underline::WasmUnderline;
use super::verbatim::WasmVerbatim;
use super::verse_block::WasmVerseBlock;
#[derive(Debug, Serialize)]
#[serde(untagged)]
pub enum WasmAstNode<'s, 'p> {
// Document Nodes
Document(WasmDocument<'s, 'p>),
Headline(WasmHeadline<'s, 'p>),
Section(WasmSection<'s, 'p>),
// Elements
Paragraph(WasmParagraph<'s, 'p>),
PlainList(WasmPlainList<'s, 'p>),
PlainListItem(WasmPlainListItem<'s, 'p>),
CenterBlock(WasmCenterBlock<'s, 'p>),
QuoteBlock(WasmQuoteBlock<'s, 'p>),
SpecialBlock(WasmSpecialBlock<'s, 'p>),
DynamicBlock(WasmDynamicBlock<'s, 'p>),
FootnoteDefinition(WasmFootnoteDefinition<'s, 'p>),
Comment(WasmComment<'s, 'p>),
Drawer(WasmDrawer<'s, 'p>),
PropertyDrawer(WasmPropertyDrawer<'s, 'p>),
NodeProperty(WasmNodeProperty<'s, 'p>),
Table(WasmTable<'s, 'p>),
TableRow(WasmTableRow<'s, 'p>),
VerseBlock(WasmVerseBlock<'s, 'p>),
CommentBlock(WasmCommentBlock<'s, 'p>),
ExampleBlock(WasmExampleBlock<'s, 'p>),
ExportBlock(WasmExportBlock<'s, 'p>),
SrcBlock(WasmSrcBlock<'s, 'p>),
Clock(WasmClock<'s, 'p>),
DiarySexp(WasmDiarySexp<'s, 'p>),
Planning(WasmPlanning<'s, 'p>),
FixedWidthArea(WasmFixedWidthArea<'s, 'p>),
HorizontalRule(WasmHorizontalRule<'s, 'p>),
Keyword(WasmKeyword<'s, 'p>),
BabelCall(WasmBabelCall<'s, 'p>),
LatexEnvironment(WasmLatexEnvironment<'s, 'p>),
// Objects
Bold(WasmBold<'s, 'p>),
Italic(WasmItalic<'s, 'p>),
Underline(WasmUnderline<'s, 'p>),
StrikeThrough(WasmStrikeThrough<'s, 'p>),
Code(WasmCode<'s, 'p>),
Verbatim(WasmVerbatim<'s, 'p>),
PlainText(WasmPlainText<'s, 'p>),
RegularLink(WasmRegularLink<'s, 'p>),
RadioLink(WasmRadioLink<'s, 'p>),
RadioTarget(WasmRadioTarget<'s, 'p>),
PlainLink(WasmPlainLink<'s, 'p>),
AngleLink(WasmAngleLink<'s, 'p>),
OrgMacro(WasmOrgMacro<'s, 'p>),
Entity(WasmEntity<'s, 'p>),
LatexFragment(WasmLatexFragment<'s, 'p>),
ExportSnippet(WasmExportSnippet<'s, 'p>),
FootnoteReference(WasmFootnoteReference<'s, 'p>),
Citation(WasmCitation<'s, 'p>),
CitationReference(WasmCitationReference<'s, 'p>),
InlineBabelCall(WasmInlineBabelCall<'s, 'p>),
InlineSourceBlock(WasmInlineSourceBlock<'s, 'p>),
LineBreak(WasmLineBreak<'s, 'p>),
Target(WasmTarget<'s, 'p>),
StatisticsCookie(WasmStatisticsCookie<'s, 'p>),
Subscript(WasmSubscript<'s, 'p>),
Superscript(WasmSuperscript<'s, 'p>),
TableCell(WasmTableCell<'s, 'p>),
Timestamp(WasmTimestamp<'s, 'p>),
}
impl<'s, 'p> WasmAstNode<'s, 'p> {}

30
src/wasm/babel_call.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::BabelCall;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmBabelCall<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmBabelCall<'s, 'p>,
BabelCall<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmBabelCall {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/bold.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Bold;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmBold<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmBold<'s, 'p>,
Bold<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmBold {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/center_block.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::CenterBlock;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmCenterBlock<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmCenterBlock<'s, 'p>,
CenterBlock<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmCenterBlock {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/citation.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Citation;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmCitation<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmCitation<'s, 'p>,
Citation<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmCitation {
standard_properties,
children: Vec::new(),
})
}
);

View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::CitationReference;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmCitationReference<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmCitationReference<'s, 'p>,
CitationReference<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmCitationReference {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/clock.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Clock;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmClock<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmClock<'s, 'p>,
Clock<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmClock {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/code.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Code;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmCode<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmCode<'s, 'p>,
Code<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmCode {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/comment.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Comment;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmComment<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmComment<'s, 'p>,
Comment<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmComment {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/comment_block.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::CommentBlock;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmCommentBlock<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmCommentBlock<'s, 'p>,
CommentBlock<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmCommentBlock {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/diary_sexp.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::DiarySexp;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmDiarySexp<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmDiarySexp<'s, 'p>,
DiarySexp<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmDiarySexp {
standard_properties,
children: Vec::new(),
})
}
);

72
src/wasm/document.rs Normal file
View File

@@ -0,0 +1,72 @@
use std::path::PathBuf;
use serde::Serialize;
use super::ast_node::WasmAstNode;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Document;
use crate::wasm::to_wasm::ToWasmStandardProperties;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmDocument<'s, 'p> {
standard_properties: WasmStandardProperties,
additional_properties: Vec<(String, &'s str)>,
children: Vec<WasmAstNode<'s, 'p>>,
category: Option<&'p str>,
path: Option<PathBuf>,
}
to_wasm!(
WasmDocument<'s, 'p>,
Document<'s>,
original,
wasm_context,
standard_properties,
{
let category = original.category.as_ref().map(String::as_str);
let path = original.path.clone();
let additional_properties: Vec<(String, &str)> = original
.get_additional_properties()
.map(|node_property| {
(
format!(":{}", node_property.property_name.to_uppercase()),
node_property.value.unwrap_or(""),
)
})
.collect();
let children = original
.zeroth_section
.iter()
.map(|child| {
child
.to_wasm(wasm_context.clone())
.map(Into::<WasmAstNode<'_, '_>>::into)
})
.chain(original.children.iter().map(|child| {
child
.to_wasm(wasm_context.clone())
.map(Into::<WasmAstNode<'_, '_>>::into)
}))
.collect::<Result<Vec<_>, _>>()?;
Ok(WasmDocument {
standard_properties,
additional_properties,
children,
category,
path,
})
}
);
impl<'s, 'p> Into<WasmAstNode<'s, 'p>> for WasmDocument<'s, 'p> {
fn into(self) -> WasmAstNode<'s, 'p> {
WasmAstNode::Document(self)
}
}

30
src/wasm/drawer.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Drawer;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmDrawer<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmDrawer<'s, 'p>,
Drawer<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmDrawer {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/dynamic_block.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::DynamicBlock;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmDynamicBlock<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmDynamicBlock<'s, 'p>,
DynamicBlock<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmDynamicBlock {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/entity.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Entity;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmEntity<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmEntity<'s, 'p>,
Entity<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmEntity {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/example_block.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::ExampleBlock;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmExampleBlock<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmExampleBlock<'s, 'p>,
ExampleBlock<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmExampleBlock {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/export_block.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::ExportBlock;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmExportBlock<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmExportBlock<'s, 'p>,
ExportBlock<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmExportBlock {
standard_properties,
children: Vec::new(),
})
}
);

View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::ExportSnippet;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmExportSnippet<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmExportSnippet<'s, 'p>,
ExportSnippet<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmExportSnippet {
standard_properties,
children: Vec::new(),
})
}
);

View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::FixedWidthArea;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmFixedWidthArea<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmFixedWidthArea<'s, 'p>,
FixedWidthArea<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmFixedWidthArea {
standard_properties,
children: Vec::new(),
})
}
);

View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::FootnoteDefinition;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmFootnoteDefinition<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmFootnoteDefinition<'s, 'p>,
FootnoteDefinition<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmFootnoteDefinition {
standard_properties,
children: Vec::new(),
})
}
);

View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::FootnoteReference;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmFootnoteReference<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmFootnoteReference<'s, 'p>,
FootnoteReference<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmFootnoteReference {
standard_properties,
children: Vec::new(),
})
}
);

36
src/wasm/headline.rs Normal file
View File

@@ -0,0 +1,36 @@
use serde::Serialize;
use super::ast_node::WasmAstNode;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Heading;
use crate::wasm::to_wasm::ToWasmStandardProperties;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "headline")]
pub struct WasmHeadline<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmHeadline<'s, 'p>,
Heading<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmHeadline {
standard_properties,
children: Vec::new(),
})
}
);
impl<'s, 'p> Into<WasmAstNode<'s, 'p>> for WasmHeadline<'s, 'p> {
fn into(self) -> WasmAstNode<'s, 'p> {
WasmAstNode::Headline(self)
}
}

View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::HorizontalRule;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmHorizontalRule<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmHorizontalRule<'s, 'p>,
HorizontalRule<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmHorizontalRule {
standard_properties,
children: Vec::new(),
})
}
);

View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::InlineBabelCall;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmInlineBabelCall<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmInlineBabelCall<'s, 'p>,
InlineBabelCall<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmInlineBabelCall {
standard_properties,
children: Vec::new(),
})
}
);

View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::InlineSourceBlock;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmInlineSourceBlock<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmInlineSourceBlock<'s, 'p>,
InlineSourceBlock<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmInlineSourceBlock {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/italic.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Italic;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmItalic<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmItalic<'s, 'p>,
Italic<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmItalic {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/keyword.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Keyword;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmKeyword<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmKeyword<'s, 'p>,
Keyword<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmKeyword {
standard_properties,
children: Vec::new(),
})
}
);

View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::LatexEnvironment;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmLatexEnvironment<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmLatexEnvironment<'s, 'p>,
LatexEnvironment<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmLatexEnvironment {
standard_properties,
children: Vec::new(),
})
}
);

View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::LatexFragment;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmLatexFragment<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmLatexFragment<'s, 'p>,
LatexFragment<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmLatexFragment {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/line_break.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::LineBreak;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmLineBreak<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmLineBreak<'s, 'p>,
LineBreak<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmLineBreak {
standard_properties,
children: Vec::new(),
})
}
);

22
src/wasm/macros.rs Normal file
View File

@@ -0,0 +1,22 @@
/// Write the implementation for the intermediate ast node.
///
/// This exists to make changing the type signature easier.
macro_rules! to_wasm {
($ostruct:ty, $istruct:ty, $original:ident, $wasm_context:ident, $standard_properties:ident, $fnbody:tt) => {
impl<'s, 'p> ToWasm<'p> for $istruct {
type Output = $ostruct;
fn to_wasm(
&'p self,
$wasm_context: crate::wasm::to_wasm::ToWasmContext<'_>,
) -> Result<Self::Output, crate::error::CustomError> {
let $original = self;
let $standard_properties =
self.to_wasm_standard_properties($wasm_context.clone())?;
$fnbody
}
}
};
}
pub(crate) use to_wasm;

69
src/wasm/mod.rs Normal file
View File

@@ -0,0 +1,69 @@
mod angle_link;
mod ast_node;
mod babel_call;
mod bold;
mod center_block;
mod citation;
mod citation_reference;
mod clock;
mod code;
mod comment;
mod comment_block;
mod diary_sexp;
mod document;
mod drawer;
mod dynamic_block;
mod entity;
mod example_block;
mod export_block;
mod export_snippet;
mod fixed_width_area;
mod footnote_definition;
mod footnote_reference;
mod headline;
mod horizontal_rule;
mod inline_babel_call;
mod inline_source_block;
mod italic;
mod keyword;
mod latex_environment;
mod latex_fragment;
mod line_break;
mod macros;
mod node_property;
mod org_macro;
mod paragraph;
mod parse_result;
mod plain_link;
mod plain_list;
mod plain_list_item;
mod plain_text;
mod planning;
mod property_drawer;
mod quote_block;
mod radio_link;
mod radio_target;
mod regular_link;
mod section;
mod special_block;
mod src_block;
mod standard_properties;
mod statistics_cookie;
mod strike_through;
mod subscript;
mod superscript;
mod table;
mod table_cell;
mod table_row;
mod target;
mod timestamp;
mod to_wasm;
mod underline;
mod verbatim;
mod verse_block;
pub use ast_node::WasmAstNode;
pub use document::WasmDocument;
pub use parse_result::ParseResult;
pub use to_wasm::ToWasm;
pub use to_wasm::ToWasmContext;

30
src/wasm/node_property.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::NodeProperty;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmNodeProperty<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmNodeProperty<'s, 'p>,
NodeProperty<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmNodeProperty {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/org_macro.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::OrgMacro;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmOrgMacro<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmOrgMacro<'s, 'p>,
OrgMacro<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmOrgMacro {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/paragraph.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Paragraph;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmParagraph<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmParagraph<'s, 'p>,
Paragraph<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmParagraph {
standard_properties,
children: Vec::new(),
})
}
);

13
src/wasm/parse_result.rs Normal file
View File

@@ -0,0 +1,13 @@
use serde::Serialize;
use super::document::WasmDocument;
#[derive(Debug, Serialize)]
#[serde(tag = "status", content = "content")]
pub enum ParseResult<'s, 'p> {
#[serde(rename = "success")]
Success(WasmDocument<'s, 'p>),
#[serde(rename = "error")]
Error(String),
}

30
src/wasm/plain_link.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::PlainLink;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmPlainLink<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmPlainLink<'s, 'p>,
PlainLink<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmPlainLink {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/plain_list.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::PlainList;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmPlainList<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmPlainList<'s, 'p>,
PlainList<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmPlainList {
standard_properties,
children: Vec::new(),
})
}
);

View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::PlainListItem;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmPlainListItem<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmPlainListItem<'s, 'p>,
PlainListItem<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmPlainListItem {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/plain_text.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::PlainText;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmPlainText<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmPlainText<'s, 'p>,
PlainText<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmPlainText {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/planning.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Planning;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmPlanning<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmPlanning<'s, 'p>,
Planning<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmPlanning {
standard_properties,
children: Vec::new(),
})
}
);

View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::PropertyDrawer;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmPropertyDrawer<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmPropertyDrawer<'s, 'p>,
PropertyDrawer<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmPropertyDrawer {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/quote_block.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::QuoteBlock;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmQuoteBlock<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmQuoteBlock<'s, 'p>,
QuoteBlock<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmQuoteBlock {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/radio_link.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::RadioLink;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmRadioLink<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmRadioLink<'s, 'p>,
RadioLink<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmRadioLink {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/radio_target.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::RadioTarget;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmRadioTarget<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmRadioTarget<'s, 'p>,
RadioTarget<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmRadioTarget {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/regular_link.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::RegularLink;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmRegularLink<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmRegularLink<'s, 'p>,
RegularLink<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmRegularLink {
standard_properties,
children: Vec::new(),
})
}
);

36
src/wasm/section.rs Normal file
View File

@@ -0,0 +1,36 @@
use serde::Serialize;
use super::ast_node::WasmAstNode;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Section;
use crate::wasm::to_wasm::ToWasmStandardProperties;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "section")]
pub struct WasmSection<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmSection<'s, 'p>,
Section<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmSection {
standard_properties,
children: Vec::new(),
})
}
);
impl<'s, 'p> Into<WasmAstNode<'s, 'p>> for WasmSection<'s, 'p> {
fn into(self) -> WasmAstNode<'s, 'p> {
WasmAstNode::Section(self)
}
}

30
src/wasm/special_block.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::SpecialBlock;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmSpecialBlock<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmSpecialBlock<'s, 'p>,
SpecialBlock<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmSpecialBlock {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/src_block.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::SrcBlock;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmSrcBlock<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmSrcBlock<'s, 'p>,
SrcBlock<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmSrcBlock {
standard_properties,
children: Vec::new(),
})
}
);

View File

@@ -0,0 +1,70 @@
use serde::Serialize;
use super::to_wasm::ToWasmContext;
use super::to_wasm::ToWasmStandardProperties;
use crate::types::PostBlank;
use crate::types::StandardProperties;
#[derive(Debug, Serialize)]
pub(crate) struct WasmStandardProperties {
begin: usize,
end: usize,
contents_begin: Option<usize>,
contents_end: Option<usize>,
post_blank: PostBlank,
}
impl<'s, SP: StandardProperties<'s>> ToWasmStandardProperties for SP {
type Output = WasmStandardProperties;
fn to_wasm_standard_properties(
&self,
wasm_context: ToWasmContext<'_>,
) -> Result<Self::Output, crate::error::CustomError> {
let (begin, end) = get_char_indices(wasm_context.full_document, self.get_source());
let (contents_begin, contents_end) = match self.get_contents() {
Some(contents) => {
let (begin, end) = get_char_indices(wasm_context.full_document, contents);
(Some(begin), Some(end))
}
None => (None, None),
};
let post_blank = self.get_post_blank();
Ok(WasmStandardProperties {
begin,
end,
contents_begin,
contents_end,
post_blank,
})
}
}
fn get_char_indices(original_document: &str, subset: &str) -> (usize, usize) {
let (begin_byte, end_byte) = get_rust_byte_offsets(original_document, subset);
// Add 1 to make this 1-based to match emacs.
let begin_char = original_document[..begin_byte].chars().count() + 1;
// Also 1-based:
let end_char = begin_char + original_document[begin_byte..end_byte].chars().count();
(begin_char, end_char)
}
/// Get the byte offset into source that the string slice exists at.
///
/// These offsets are zero-based.
fn get_rust_byte_offsets(original_document: &str, subset: &str) -> (usize, usize) {
debug_assert!(is_slice_of(original_document, subset));
let offset = subset.as_ptr() as usize - original_document.as_ptr() as usize;
let end = offset + subset.len();
(offset, end)
}
/// Check if the child string slice is a slice of the parent string slice.
fn is_slice_of(parent: &str, child: &str) -> bool {
let parent_start = parent.as_ptr() as usize;
let parent_end = parent_start + parent.len();
let child_start = child.as_ptr() as usize;
let child_end = child_start + child.len();
child_start >= parent_start && child_end <= parent_end
}

View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::StatisticsCookie;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmStatisticsCookie<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmStatisticsCookie<'s, 'p>,
StatisticsCookie<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmStatisticsCookie {
standard_properties,
children: Vec::new(),
})
}
);

View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::StrikeThrough;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmStrikeThrough<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmStrikeThrough<'s, 'p>,
StrikeThrough<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmStrikeThrough {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/subscript.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Subscript;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmSubscript<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmSubscript<'s, 'p>,
Subscript<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmSubscript {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/superscript.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Superscript;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmSuperscript<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmSuperscript<'s, 'p>,
Superscript<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmSuperscript {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/table.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Table;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmTable<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmTable<'s, 'p>,
Table<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmTable {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/table_cell.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::TableCell;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmTableCell<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmTableCell<'s, 'p>,
TableCell<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmTableCell {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/table_row.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::TableRow;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmTableRow<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmTableRow<'s, 'p>,
TableRow<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmTableRow {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/target.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Target;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmTarget<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmTarget<'s, 'p>,
Target<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmTarget {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/timestamp.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Timestamp;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmTimestamp<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmTimestamp<'s, 'p>,
Timestamp<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmTimestamp {
standard_properties,
children: Vec::new(),
})
}
);

27
src/wasm/to_wasm.rs Normal file
View File

@@ -0,0 +1,27 @@
use crate::error::CustomError;
pub trait ToWasm<'p> {
type Output;
fn to_wasm(&'p self, full_document: ToWasmContext<'_>) -> Result<Self::Output, CustomError>;
}
pub(crate) trait ToWasmStandardProperties {
type Output;
fn to_wasm_standard_properties(
&self,
wasm_context: ToWasmContext<'_>,
) -> Result<Self::Output, CustomError>;
}
#[derive(Debug, Clone)]
pub struct ToWasmContext<'s> {
pub(crate) full_document: &'s str,
}
impl<'s> ToWasmContext<'s> {
pub fn new(full_document: &'s str) -> ToWasmContext<'s> {
ToWasmContext { full_document }
}
}

30
src/wasm/underline.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Underline;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmUnderline<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmUnderline<'s, 'p>,
Underline<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmUnderline {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/verbatim.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::Verbatim;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmVerbatim<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmVerbatim<'s, 'p>,
Verbatim<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmVerbatim {
standard_properties,
children: Vec::new(),
})
}
);

30
src/wasm/verse_block.rs Normal file
View File

@@ -0,0 +1,30 @@
use serde::Serialize;
use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm;
use crate::types::VerseBlock;
use crate::wasm::to_wasm::ToWasmStandardProperties;
use crate::wasm::WasmAstNode;
#[derive(Debug, Serialize)]
#[serde(tag = "ast_node")]
#[serde(rename = "org-data")]
pub struct WasmVerseBlock<'s, 'p> {
standard_properties: WasmStandardProperties,
children: Vec<WasmAstNode<'s, 'p>>,
}
to_wasm!(
WasmVerseBlock<'s, 'p>,
VerseBlock<'s>,
original,
wasm_context,
standard_properties,
{
Ok(WasmVerseBlock {
standard_properties,
children: Vec::new(),
})
}
);

185
src/wasm_test/compare.rs Normal file
View File

@@ -0,0 +1,185 @@
use std::borrow::Cow;
use crate::compare::Token;
use crate::wasm::WasmAstNode;
use crate::wasm::WasmDocument;
pub fn wasm_compare_document<'b, 's, 'p>(
source: &'s str,
emacs: &'b Token<'s>,
wasm: WasmDocument<'s, 'p>,
) -> Result<WasmDiffEntry<'b, 's>, Box<dyn std::error::Error>> {
// wasm_compare_ast_node(
todo!()
}
#[derive(Debug)]
pub enum WasmDiffEntry<'b, 's> {
WasmDiffResult(WasmDiffResult<'b, 's>),
WasmDiffLayer(WasmDiffLayer<'b, 's>),
}
#[derive(Debug)]
pub struct WasmDiffResult<'b, 's> {
status: WasmDiffStatus,
name: Cow<'s, str>,
message: Option<String>,
children: Vec<WasmDiffEntry<'b, 's>>,
rust_source: &'s str,
#[allow(dead_code)]
emacs_token: &'b Token<'s>,
}
#[derive(Debug)]
pub(crate) enum WasmDiffStatus {
Good,
Bad,
}
#[derive(Debug)]
pub struct WasmDiffLayer<'b, 's> {
name: Cow<'s, str>,
children: Vec<WasmDiffEntry<'b, 's>>,
}
impl<'b, 's> WasmDiffEntry<'b, 's> {
// fn has_bad_children(&self) -> bool {
// match self {
// DiffEntry::DiffResult(diff) => &diff.children,
// DiffEntry::DiffLayer(diff) => &diff.children,
// }
// .iter()
// .any(|child| child.is_immediately_bad() || child.has_bad_children())
// }
// fn is_immediately_bad(&self) -> bool {
// match self {
// DiffEntry::DiffResult(diff) => matches!(diff.status, DiffStatus::Bad),
// DiffEntry::DiffLayer(_) => false,
// }
// }
pub fn is_bad(&self) -> bool {
todo!()
// self.is_immediately_bad() || self.has_bad_children()
}
pub fn print(&self, original_document: &str) -> Result<(), Box<dyn std::error::Error>> {
self.print_indented(0, original_document)
}
fn print_indented(
&self,
indentation: usize,
original_document: &str,
) -> Result<(), Box<dyn std::error::Error>> {
todo!()
// match self {
// WasmDiffEntry::WasmDiffResult(diff) => {
// diff.print_indented(indentation, original_document)
// }
// WasmDiffEntry::WasmDiffLayer(diff) => {
// diff.print_indented(indentation, original_document)
// }
// }
}
}
fn wasm_compare_ast_node<'b, 's, 'p>(
source: &'s str,
emacs: &'b Token<'s>,
wasm: WasmAstNode<'s, 'p>,
) -> Result<WasmDiffEntry<'b, 's>, Box<dyn std::error::Error>> {
match wasm {
WasmAstNode::Document(_) => todo!(),
WasmAstNode::Headline(_) => todo!(),
WasmAstNode::Section(_) => todo!(),
WasmAstNode::Paragraph(_) => todo!(),
WasmAstNode::PlainList(_) => todo!(),
WasmAstNode::PlainListItem(_) => todo!(),
WasmAstNode::CenterBlock(_) => todo!(),
WasmAstNode::QuoteBlock(_) => todo!(),
WasmAstNode::SpecialBlock(_) => todo!(),
WasmAstNode::DynamicBlock(_) => todo!(),
WasmAstNode::FootnoteDefinition(_) => todo!(),
WasmAstNode::Comment(_) => todo!(),
WasmAstNode::Drawer(_) => todo!(),
WasmAstNode::PropertyDrawer(_) => todo!(),
WasmAstNode::NodeProperty(_) => todo!(),
WasmAstNode::Table(_) => todo!(),
WasmAstNode::TableRow(_) => todo!(),
WasmAstNode::VerseBlock(_) => todo!(),
WasmAstNode::CommentBlock(_) => todo!(),
WasmAstNode::ExampleBlock(_) => todo!(),
WasmAstNode::ExportBlock(_) => todo!(),
WasmAstNode::SrcBlock(_) => todo!(),
WasmAstNode::Clock(_) => todo!(),
WasmAstNode::DiarySexp(_) => todo!(),
WasmAstNode::Planning(_) => todo!(),
WasmAstNode::FixedWidthArea(_) => todo!(),
WasmAstNode::HorizontalRule(_) => todo!(),
WasmAstNode::Keyword(_) => todo!(),
WasmAstNode::BabelCall(_) => todo!(),
WasmAstNode::LatexEnvironment(_) => todo!(),
WasmAstNode::Bold(_) => todo!(),
WasmAstNode::Italic(_) => todo!(),
WasmAstNode::Underline(_) => todo!(),
WasmAstNode::StrikeThrough(_) => todo!(),
WasmAstNode::Code(_) => todo!(),
WasmAstNode::Verbatim(_) => todo!(),
WasmAstNode::PlainText(_) => todo!(),
WasmAstNode::RegularLink(_) => todo!(),
WasmAstNode::RadioLink(_) => todo!(),
WasmAstNode::RadioTarget(_) => todo!(),
WasmAstNode::PlainLink(_) => todo!(),
WasmAstNode::AngleLink(_) => todo!(),
WasmAstNode::OrgMacro(_) => todo!(),
WasmAstNode::Entity(_) => todo!(),
WasmAstNode::LatexFragment(_) => todo!(),
WasmAstNode::ExportSnippet(_) => todo!(),
WasmAstNode::FootnoteReference(_) => todo!(),
WasmAstNode::Citation(_) => todo!(),
WasmAstNode::CitationReference(_) => todo!(),
WasmAstNode::InlineBabelCall(_) => todo!(),
WasmAstNode::InlineSourceBlock(_) => todo!(),
WasmAstNode::LineBreak(_) => todo!(),
WasmAstNode::Target(_) => todo!(),
WasmAstNode::StatisticsCookie(_) => todo!(),
WasmAstNode::Subscript(_) => todo!(),
WasmAstNode::Superscript(_) => todo!(),
WasmAstNode::TableCell(_) => todo!(),
WasmAstNode::Timestamp(_) => todo!(),
}
todo!()
}
// fn wasm_compare_list<'b, 's, EI, WI, WC>(
// source: &'s str,
// emacs: EI,
// wasm: WI,
// // emacs: &'b Token<'s>,
// // wasm: WasmDocument<'s>,
// ) -> Result<WasmDiffEntry<'b, 's>, Box<dyn std::error::Error>>
// where
// EI: Iterator<Item = &'b Token<'s>> + ExactSizeIterator,
// WI: Iterator<Item = WC>,
// WasmAstNode<'b, 's>: From<WC>,
// {
// let mut this_status = WasmDiffStatus::Good;
// let mut child_status = Vec::new();
// let mut message = None;
// todo!()
// }
fn impl_wasm_compare_document<'b, 's, 'p>(
source: &'s str,
emacs: &'b Token<'s>,
wasm: WasmDocument<'s, 'p>,
) -> Result<WasmDiffEntry<'b, 's>, Box<dyn std::error::Error>> {
let mut this_status = WasmDiffStatus::Good;
// let mut child_status = Vec::new();
// let mut message = None;
todo!()
}

5
src/wasm_test/mod.rs Normal file
View File

@@ -0,0 +1,5 @@
mod compare;
mod runner;
pub use runner::wasm_run_anonymous_compare;
pub use runner::wasm_run_anonymous_compare_with_settings;

61
src/wasm_test/runner.rs Normal file
View File

@@ -0,0 +1,61 @@
use super::compare::wasm_compare_document;
use crate::compare::sexp;
use crate::context::GlobalSettings;
use crate::parser::parse_with_settings;
use crate::util::emacs_parse_anonymous_org_document;
use crate::util::foreground_color;
use crate::util::print_versions;
use crate::util::reset_color;
use crate::wasm::ToWasm;
use crate::wasm::ToWasmContext;
pub async fn wasm_run_anonymous_compare<P: AsRef<str>>(
org_contents: P,
) -> Result<bool, Box<dyn std::error::Error>> {
wasm_run_anonymous_compare_with_settings(org_contents, &GlobalSettings::default(), false).await
}
pub async fn wasm_run_anonymous_compare_with_settings<'g, 's, P: AsRef<str>>(
org_contents: P,
global_settings: &GlobalSettings<'g, 's>,
silent: bool,
) -> Result<bool, Box<dyn std::error::Error>> {
// TODO: This is a work-around to pretend that dos line endings do not exist. It would be better to handle the difference in line endings.
let org_contents = org_contents.as_ref().replace("\r\n", "\n");
let org_contents = org_contents.as_str();
if !silent {
print_versions().await?;
}
let rust_parsed = parse_with_settings(org_contents, global_settings)?;
let to_wasm_context = ToWasmContext::new(org_contents);
let wasm_parsed = rust_parsed
.to_wasm(to_wasm_context)
.map_err(|_e| "Failed to convert to wasm.")?;
let org_sexp = emacs_parse_anonymous_org_document(org_contents, global_settings).await?;
let (_remaining, parsed_sexp) = sexp(org_sexp.as_str()).map_err(|e| e.to_string())?;
if !silent {
println!("{}\n\n\n", org_contents);
println!("{}", org_sexp);
println!("{:#?}", rust_parsed);
println!("{}", serde_json::to_string(&wasm_parsed)?);
}
// We do the diffing after printing out both parsed forms in case the diffing panics
let diff_result = wasm_compare_document(org_contents, &parsed_sexp, wasm_parsed)?;
if !silent {
diff_result.print(org_contents)?;
}
if diff_result.is_bad() {
return Ok(false);
} else if !silent {
println!(
"{color}Entire document passes.{reset}",
color = foreground_color(0, 255, 0),
reset = reset_color(),
);
}
Ok(true)
}