-rw-r--r--other_crates.md7
-rw-r--r--src/build/builders/core/value.mmd51
-rw-r--r--src/build/builders/core/value.rs4
-rw-r--r--src/build/builders/core/value2.mmd8
-rw-r--r--src/doc_macro.rs17
-rw-r--r--src/doc_mermaid_injector.js146
-rw-r--r--src/lib.rs1
-rw-r--r--src/macros/build.rs1
-rw-r--r--tests/builder_value.rs47
9 files changed, 280 insertions, 2 deletions
diff --git a/other_crates.md b/other_crates.md
new file mode 100644
index 0000000..9e21275
--- /dev/null
+++ b/other_crates.md
@@ -0,0 +1,7 @@
+https://docs.rs/serde/latest/serde/
+
+https://docs.rs/miniserde/0.1.39/miniserde/
+
+https://docs.rs/musli/0.0.122/musli/
+
+https://docs.rs/rkyv/latest/rkyv/
diff --git a/src/build/builders/core/value.mmd b/src/build/builders/core/value.mmd
new file mode 100644
index 0000000..806e622
--- /dev/null
+++ b/src/build/builders/core/value.mmd
@@ -0,0 +1,51 @@
+sequenceDiagram
+ participant walker as Walker
+ participant request as RequestHint
+ participant value as Value\nT
+ participant value_borrow as Value\n&'ctx T
+ participant value_temp_borrow as Value\n&'a T
+ participant value_mut_borrow as Value\n&'ctx mut T
+ participant value_temp_mut_borrow as Value\n&'a mut T
+
+ Note over request,value_temp_mut_borrow: ValueBuilder
+
+ rect rgba(120, 120, 120, 0.2)
+ note left of walker: Value Flow\nOwned
+ walker ->> value: visit()
+ end
+ rect rgba(120, 120, 120, 0.2)
+ note left of walker: Value Flow\nContext Borrowed
+ walker ->> value_borrow: visit()
+ end
+ rect rgba(120, 120, 120, 0.2)
+ note left of walker: Value Flow\nTemp Borrowed
+ walker ->> value_temp_borrow: visit()
+ end
+ rect rgba(120, 120, 120, 0.2)
+ note left of walker: Value Flow\nContext Mutable Borrowed
+ walker ->> value_mut_borrow: visit()
+ end
+ rect rgba(120, 120, 120, 0.2)
+ note left of walker: Value Flow\nTemp Mutable Borrowed
+ walker ->> value_temp_mut_borrow: visit()
+ end
+ rect rgba(120, 120, 120, 0.2)
+ note left of walker: Request Hint Flow
+ walker ->> request: request_hint()
+ alt Walker supports by ownership
+ request ->> walker: hint<Value<T>>()
+ walker ->> value: visit()
+ else Walker supports by context borrow
+ request ->> walker: hint<Value<&'ctx T>>()
+ walker ->> value_borrow: visit()
+ else Walker supports by temp borrow
+ request ->> walker: hint<Value<&'a T>>()
+ walker ->> value_temp_borrow: visit()
+ else Walker supports by context mutable borrow
+ request ->> walker: hint<Value<&'ctx mut T>>()
+ walker ->> value_mut_borrow: visit()
+ else Walker supports by tmep mutable borrow
+ request ->> walker: hint<Value<&'a mut T>>()
+ walker ->> value_temp_mut_borrow: visit()
+ end
+ end
diff --git a/src/build/builders/core/value.rs b/src/build/builders/core/value.rs
index d82ea1e..b969ac2 100644
--- a/src/build/builders/core/value.rs
+++ b/src/build/builders/core/value.rs
@@ -40,6 +40,10 @@ pub enum NotCloneable {}
/// Builder for `'static` values.
///
/// This builder only uses the [`Value`] protocol.
+///
+#[doc = crate::doc_macro::mermaid!("value.mmd", 100)]
+///
+/// After
pub struct ValueBuilder<T, Clone, E> {
value: Option<T>,
_marker: Marker<(E, Clone)>,
diff --git a/src/build/builders/core/value2.mmd b/src/build/builders/core/value2.mmd
new file mode 100644
index 0000000..b5572e2
--- /dev/null
+++ b/src/build/builders/core/value2.mmd
@@ -0,0 +1,8 @@
+sequenceDiagram
+ participant walker as Walker
+ participant request as RequestHint
+ participant value as Value\nT
+ alt Request Hint Flow
+ walker ->> request: request_hint()
+ request ->> walker: hint&lt;Value&lt;OwnedStatic&lt;T&gt;&gt;&gt;()
+ end
diff --git a/src/doc_macro.rs b/src/doc_macro.rs
new file mode 100644
index 0000000..6cf009a
--- /dev/null
+++ b/src/doc_macro.rs
@@ -0,0 +1,17 @@
+macro_rules! mermaid {
+ ($file:literal, $height:literal) => {
+ concat!(
+ "<pre class=\"mermaid\" style=\"padding:0;max-height:90vh;height:",
+ stringify!($height),
+ "vw;\">\n",
+ "<div style=\"visibility:hidden;\">\n",
+ include_str!($file),
+ "\n<div>\n",
+ "</pre>\n\n",
+ "<script type=\"module\">\n",
+ include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc_mermaid_injector.js")),
+ "</script>\n\n"
+ )
+ };
+}
+pub(crate) use mermaid;
diff --git a/src/doc_mermaid_injector.js b/src/doc_mermaid_injector.js
new file mode 100644
index 0000000..5436120
--- /dev/null
+++ b/src/doc_mermaid_injector.js
@@ -0,0 +1,146 @@
+if(!window.__injector_global_mermaid) {
+ const mermaid_module = await import("https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs")
+
+ if(!window.__injector_global_mermaid) {
+ window.__injector_global_mermaid = mermaid_module.default;
+
+ const mermaid = window.__injector_global_mermaid;
+
+ var doc_theme = localStorage.getItem("rustdoc-theme");
+
+ if (doc_theme === "dark" || doc_theme === "ayu") {
+ mermaid.initialize({theme: "dark", startOneLoad: false});
+ } else {
+ mermaid.initialize({startOneLoad: false});
+ }
+
+ let scripts = Array
+ .from(document.querySelectorAll('script'))
+ .map(scr => scr.src);
+
+ if (!scripts.includes('svg-pan-zoom.min.js')) {
+ var tag = document.createElement('script');
+ tag.src = 'https://cdn.jsdelivr.net/npm/[email protected]/dist/svg-pan-zoom.min.js';
+ document.getElementsByTagName('body')[0].appendChild(tag);
+ }
+
+ var tag = document.createElement('style');
+ tag.innerHTML = `
+ svg {
+ border: 3px solid #85858500;
+ }
+ svg.active {
+ border: 3px solid #85858560;
+ }
+ svg.hovered {
+ border: 3px solid #85858530;
+ }
+ svg.hovered.active {
+ border: 3px solid #85858590;
+ }
+ `
+ document.getElementsByTagName('body')[0].appendChild(tag);
+
+ window.addEventListener('load', run_mermaid())
+ }
+}
+
+async function run_mermaid() {
+ const mermaid = window.__injector_global_mermaid;
+
+ const diagrams = document.getElementsByClassName("mermaid");
+ for (let i = 0; i < diagrams.length; i++) {
+ const diagram = diagrams.item(i);
+
+ const text = diagram.textContent.replaceAll("\\n", "<br>");
+
+ diagram.innerHTML = "<svg id=\"diagram" + i + "\"></svg>"
+
+ try {
+ var result = await mermaid.render("diagram" + i, text, diagram)
+ } catch (error) {
+ const error_div = diagram.children[0]
+
+ error_div.style.height = "100%"
+
+ const error_svg = error_div.children[0]
+
+ error_svg.style.height = "100%"
+ error_svg.style.display = "block"
+ error_svg.style.margin = "auto"
+
+ continue
+ }
+ console.log(result)
+ var { svg } = result
+
+ diagram.innerHTML = svg;
+
+ svg = document.getElementById("diagram" + i)
+
+ svg.style.maxWidth = ""
+ svg.style.height = "100%"
+ svg.style.width = "100%"
+ svg.style.display = "block"
+ svg.style.cursor = "default"
+
+ var svg_active = false;
+ var mouse_moved = false;
+ var svg_hovered = false;
+
+ var pan_zoom;
+ pan_zoom = svgPanZoom("#diagram" + i, {
+ zoomEnabled: false,
+ panEnabled: false,
+ zoomScaleSensitivity: 0.3,
+ controlIconsEnabled: false,
+ customEventsHandler: {
+ init: function(options) {
+ function update_svg_class(){
+ options.svgElement.setAttribute('class', '' + (svg_active ? 'active':'') + (svg_hovered ? ' hovered':''))
+ }
+
+ this.listeners = {
+ mousedown: function() {
+ mouse_moved = false
+ },
+ mousemove: function() {
+ mouse_moved = true
+ },
+ mouseup: function() {
+ if (!mouse_moved) {
+ if (svg_active) {
+ options.instance.disableZoom()
+ options.instance.disablePan()
+ svg_active = false
+ } else {
+ options.instance.enableZoom()
+ options.instance.enablePan()
+ svg_active = true
+ }
+ update_svg_class()
+ }
+ },
+ mouseenter: function() {
+ svg_hovered = true
+ update_svg_class()
+ },
+ mouseleave: function() {
+ svg_hovered = false
+ update_svg_class()
+ },
+ }
+
+ for (var eventName in this.listeners){
+ options.svgElement.addEventListener(eventName, this.listeners[eventName])
+ }
+ },
+ destroy: function(options){
+ for (var eventName in this.listeners){
+ options.svgElement.removeEventListener(eventName, this.listeners[eventName])
+ }
+ }
+ }
+ })
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 7f38206..88d550a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -16,6 +16,7 @@ pub mod protocol;
pub mod symbol;
mod transform;
mod walk;
+mod doc_macro;
use core::ops::ControlFlow;
diff --git a/src/macros/build.rs b/src/macros/build.rs
index 9e7ced9..7eb3fbe 100644
--- a/src/macros/build.rs
+++ b/src/macros/build.rs
@@ -8,6 +8,7 @@ macro_rules! Build {
} => {
#[allow(non_upper_case_globals, non_snake_case, non_camel_case_types)]
const _: () = {
+ // add a module here to seal fields.
impl<'ctx, M: 'ctx, E: $crate::effect::Effect> $crate::Build<'ctx, M, E> for $name {
type Builder = $crate::builders::core::r#struct::StructBuilder<'ctx, __Info, M, E>;
}
diff --git a/tests/builder_value.rs b/tests/builder_value.rs
index 92f3450..9f52252 100644
--- a/tests/builder_value.rs
+++ b/tests/builder_value.rs
@@ -1,7 +1,8 @@
mod common;
+use common::walker::MockWalker;
use treaty::{
- any::OwnedStatic,
+ any::{BorrowedStatic, OwnedStatic, TempBorrowedStatic},
effect::blocking::Blocking,
protocol::{
visitor::{request_hint, ValueProto},
@@ -10,7 +11,7 @@ use treaty::{
BuildExt as _, Builder as _, Flow,
};
-use crate::common::protocol::hint::MockHintWalker;
+use crate::common::protocol::{hint::MockHintWalker, value::ValueVisitorExt as _};
#[test]
fn value_builder_gives_value_protocol_as_hint() {
@@ -36,3 +37,45 @@ fn value_builder_gives_value_protocol_as_hint() {
// The builder should have the value.
assert_eq!(builder.build().value().unwrap(), 42);
}
+
+#[test]
+fn value_builder_can_use_an_owned_value_or_a_borrowed_value() {
+ assert_eq!(
+ i32::build({
+ let mut walker = MockWalker::<(), ()>::new();
+ walker.expect_walk().once().returning(|visitor| {
+ visitor.visit_value_and_done(OwnedStatic(1));
+ Ok(())
+ });
+ walker
+ })
+ .unwrap(),
+ 1
+ );
+
+ assert_eq!(
+ i32::build({
+ let mut walker = MockWalker::<(), ()>::new();
+ walker.expect_walk().once().returning(|visitor| {
+ visitor.visit_value_and_done(BorrowedStatic(&2));
+ Ok(())
+ });
+ walker
+ })
+ .unwrap(),
+ 2
+ );
+
+ assert_eq!(
+ i32::build({
+ let mut walker = MockWalker::<(), ()>::new();
+ walker.expect_walk().once().returning(|visitor| {
+ visitor.visit_value_and_done(TempBorrowedStatic(&3));
+ Ok(())
+ });
+ walker
+ })
+ .unwrap(),
+ 3
+ );
+}