Skip to content

Commit

Permalink
Add start of pretty-format
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielleHuisman committed Aug 21, 2024
1 parent 8034381 commit 458f3ca
Show file tree
Hide file tree
Showing 10 changed files with 375 additions and 4 deletions.
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/dom/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ static CONFIG: LazyLock<Arc<Mutex<Config>>> = LazyLock::new(|| {
show_original_stack_trace: false,
throw_suggestions: false,
get_element_error: Arc::new(|message, container| {
let prettified_dom = pretty_dom(Some(container));
let prettified_dom = pretty_dom(Some(container.into()), None);

let default_ignore = {
let config = CONFIG.lock().expect("Config mutex should be acquired.");
Expand Down
7 changes: 7 additions & 0 deletions packages/dom/src/helpers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use web_sys::{window, Document};

pub fn get_document() -> Document {
window()
.and_then(|window| window.document())
.expect("Could not find default container")
}
1 change: 1 addition & 0 deletions packages/dom/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod config;
mod error;
mod get_node_text;
mod get_queries_for_element;
mod helpers;
mod matches;
mod pretty_dom;
pub mod queries;
Expand Down
46 changes: 43 additions & 3 deletions packages/dom/src/pretty_dom.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,46 @@
use web_sys::Element;
use web_sys::{Document, Element};

use crate::helpers::get_document;

pub enum DocumentOrElement {
Document(Document),
Element(Element),
}

impl From<Document> for DocumentOrElement {
fn from(value: Document) -> Self {
Self::Document(value)
}
}

impl From<Element> for DocumentOrElement {
fn from(value: Element) -> Self {
Self::Element(value)
}
}

pub fn pretty_dom(dom: Option<DocumentOrElement>, max_length: Option<usize>) -> String {
let dom = dom.unwrap_or_else(|| get_document().into());
let max_length = max_length.unwrap_or(7000);

if max_length == 0 {
return "".into();
}

let _dom = match dom {
DocumentOrElement::Document(document) => match document.document_element() {
Some(element) => DocumentOrElement::Element(element),
None => DocumentOrElement::Document(document),
},
dom => dom,
};

pub fn pretty_dom(_dom: Option<Element>) -> String {
// TODO
"".into()
let debug_content = "".to_string();

if debug_content.len() > max_length {
format!("{}...", &debug_content[0..max_length])
} else {
debug_content
}
}
22 changes: 22 additions & 0 deletions packages/pretty-format/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "pretty-format"
description = "Rust port of pretty-format."

authors.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
version.workspace = true

[dependencies]
ansi-style = "1.2.1"
thiserror.workspace = true
wasm-bindgen.workspace = true
web-sys = { workspace = true, features = [
"Document",
"Element",
"HtmlElement",
"HtmlInputElement",
"NodeList",
"Window",
] }
3 changes: 3 additions & 0 deletions packages/pretty-format/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Rust Pretty Format

Rust port of [pretty-format](https://github.com/jestjs/jest/tree/main/packages/pretty-format).
7 changes: 7 additions & 0 deletions packages/pretty-format/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use thiserror::Error;

#[derive(Debug, Error, PartialEq)]
pub enum PrettyFormatError {
#[error("{0}")]
Configuration(String),
}
174 changes: 174 additions & 0 deletions packages/pretty-format/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
// TODO: remove
#![allow(dead_code, unused)]

mod error;
mod types;

use std::rc::Rc;

pub use error::PrettyFormatError;
pub use types::{Config, PrettyFormatOptions, PrettyFormatValue};

use types::{Colors, Plugin, Plugins, Refs};

pub fn print_basic_value(
val: &PrettyFormatValue,
print_function_name: bool,
escape_regex: bool,
escape_string: bool,
) -> Option<String> {
match val {
PrettyFormatValue::Bool(val) => Some(format!("{val}")),
// _ => None,
}
}

pub fn print_complex_value(
val: &PrettyFormatValue,
config: Config,
indentation: String,
depth: usize,
refs: Refs,
has_called_to_json: Option<bool>,
) -> String {
"".into()
}

fn print_plugin(
plugin: Rc<dyn Plugin>,
val: PrettyFormatValue,
config: Config,
indentation: String,
depth: usize,
refs: Refs,
) -> String {
plugin.serialize(val, config, indentation, depth, refs, &printer)
}

fn find_plugin(plugins: &Plugins, val: &PrettyFormatValue) -> Option<Rc<dyn Plugin>> {
plugins.iter().find(|plugin| plugin.test(val)).cloned()
}

fn printer(
val: PrettyFormatValue,
config: Config,
indentation: String,
depth: usize,
refs: Refs,
has_called_to_json: Option<bool>,
) -> String {
"".into()
}

fn validate_options(options: &PrettyFormatOptions) -> Result<(), PrettyFormatError> {
if options.min.is_some() && options.indent.is_some_and(|indent| indent != 0) {
Err(PrettyFormatError::Configuration(
"Options `min` and `indent` cannot be used togther.".into(),
))
} else {
Ok(())
}
}

fn get_colors_highlight(options: &PrettyFormatOptions) -> Colors {
let theme = options.theme.clone().unwrap_or_default();

Colors {
comment: theme.comment,
content: theme.content,
prop: theme.prop,
tag: theme.tag,
value: theme.value,
}
}

fn get_colors_empty() -> Colors {
Colors::default()
}

fn get_print_function_name(options: &PrettyFormatOptions) -> bool {
options.print_function_name.unwrap_or(true)
}

fn get_escape_regex(options: &PrettyFormatOptions) -> bool {
options.escape_regex.unwrap_or(false)
}

fn get_escape_string(options: &PrettyFormatOptions) -> bool {
options.escape_string.unwrap_or(true)
}

fn get_config(options: PrettyFormatOptions) -> Config {
Config {
call_to_json: options.call_to_json.unwrap_or(true),
compare_keys: options.compare_keys.clone(),
colors: match options.highlight {
Some(true) => get_colors_highlight(&options),
_ => get_colors_empty(),
},
escape_regex: options.escape_regex.unwrap_or(false),
escape_string: options.escape_string.unwrap_or(true),
indent: match options.min {
Some(true) => "".into(),
_ => create_indent(options.indent.unwrap_or(2)),
},
max_depth: options.max_depth.unwrap_or(usize::MAX),
max_width: options.max_width.unwrap_or(usize::MAX),
min: options.min.unwrap_or(false),
plugins: options.plugins.unwrap_or_default(),
print_function_name: options.print_function_name.unwrap_or(true),
spacing_inner: match options.min {
Some(true) => " ",
_ => "\n",
}
.into(),
spacing_outer: match options.min {
Some(true) => "",
_ => "\n",
}
.into(),
}
}

fn create_indent(indent: usize) -> String {
" ".repeat(indent + 1)
}

pub fn format(
val: PrettyFormatValue,
options: PrettyFormatOptions,
) -> Result<String, PrettyFormatError> {
validate_options(&options)?;

if let Some(plugins) = &options.plugins {
if let Some(plugin) = find_plugin(plugins, &val) {
return Ok(print_plugin(
plugin,
val,
get_config(options),
"".into(),
0,
vec![],
));
}
}

let basic_result = print_basic_value(
&val,
get_print_function_name(&options),
get_escape_regex(&options),
get_escape_string(&options),
);
if let Some(basic_result) = basic_result {
Ok(basic_result)
} else {
Ok(print_complex_value(
&val,
get_config(options),
"".into(),
0,
vec![],
None,
))
}
}
Loading

0 comments on commit 458f3ca

Please sign in to comment.