Docs: Comprehensive inline rustdoc and architectural summary PDF
This commit is contained in:
0
target/doc/.lock
Normal file
0
target/doc/.lock
Normal file
1
target/doc/chrs_agent/all.html
Normal file
1
target/doc/chrs_agent/all.html
Normal file
@@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="List of all items in this crate"><title>List of all items in this crate</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_agent" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod sys"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_agent/index.html">chrs_<wbr>agent</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h3><a href="#structs">Crate Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li><li><a href="#functions" title="Functions">Functions</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><h1>List of all items</h1><h3 id="structs">Structs</h3><ul class="all-items"><li><a href="struct.CHORUSAgent.html">CHORUSAgent</a></li></ul><h3 id="functions">Functions</h3><ul class="all-items"><li><a href="fn.main.html">main</a></li></ul></section></div></main></body></html>
|
||||
5
target/doc/chrs_agent/fn.main.html
Normal file
5
target/doc/chrs_agent/fn.main.html
Normal file
@@ -0,0 +1,5 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Entry point for the CHORUS agent binary."><title>main in chrs_agent - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_agent" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="sidebar-items.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc fn"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_agent/index.html">chrs_<wbr>agent</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><div class="rustdoc-breadcrumbs"><a href="index.html">chrs_agent</a></div><h1>Function <span class="fn">main</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/chrs_agent/main.rs.html#106-115">Source</a> </span></div><pre class="rust item-decl"><code>pub(crate) fn main() -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.unit.html">()</a>, <a class="struct" href="https://doc.rust-lang.org/1.87.0/alloc/boxed/struct.Box.html" title="struct alloc::boxed::Box">Box</a><dyn <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/error/trait.Error.html" title="trait core::error::Error">Error</a>>></code></pre><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Entry point for the CHORUS agent binary.</p>
|
||||
<p>It creates a data directory under <code>/home/Tony/rust/projects/reset/CHORUS/data</code>
|
||||
(note the capitalised <code>Tony</code> matches the original path), initialises the
|
||||
<code>CHORUSAgent</code>, and starts its run loop.</p>
|
||||
</div></details></section></div></main></body></html>
|
||||
1
target/doc/chrs_agent/index.html
Normal file
1
target/doc/chrs_agent/index.html
Normal file
@@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="API documentation for the Rust `chrs_agent` crate."><title>chrs_agent - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_agent" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="../crates.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod crate"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_agent/index.html">chrs_<wbr>agent</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><ul class="block"><li><a id="all-types" href="all.html">All Items</a></li></ul><section id="rustdoc-toc"><h3><a href="#structs">Crate Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li><li><a href="#functions" title="Functions">Functions</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1>Crate <span>chrs_agent</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/chrs_agent/main.rs.html#1-115">Source</a> </span></div><h2 id="structs" class="section-header">Structs<a href="#structs" class="anchor">§</a></h2><dl class="item-table"><dt><a class="struct" href="struct.CHORUSAgent.html" title="struct chrs_agent::CHORUSAgent">CHORUS<wbr>Agent</a></dt><dd>Represents a running CHORUS agent.</dd></dl><h2 id="functions" class="section-header">Functions<a href="#functions" class="anchor">§</a></h2><dl class="item-table"><dt><a class="fn" href="fn.main.html" title="fn chrs_agent::main">main</a><span title="Restricted Visibility"> 🔒</span> </dt><dd>Entry point for the CHORUS agent binary.</dd></dl></section></div></main></body></html>
|
||||
1
target/doc/chrs_agent/sidebar-items.js
Normal file
1
target/doc/chrs_agent/sidebar-items.js
Normal file
@@ -0,0 +1 @@
|
||||
window.SIDEBAR_ITEMS = {"fn":["main"],"struct":["CHORUSAgent"]};
|
||||
45
target/doc/chrs_agent/struct.CHORUSAgent.html
Normal file
45
target/doc/chrs_agent/struct.CHORUSAgent.html
Normal file
@@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Represents a running CHORUS agent."><title>CHORUSAgent in chrs_agent - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_agent" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="sidebar-items.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc struct"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_agent/index.html">chrs_<wbr>agent</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">CHORUS<wbr>Agent</a></h2><h3><a href="#">Sections</a></h3><ul class="block top-toc"><li><a href="#fields-1" title="Fields">Fields</a></li><li><a href="#rationale" title="Rationale">Rationale</a></li></ul><h3><a href="#fields">Fields</a></h3><ul class="block structfield"><li><a href="#structfield.graph" title="graph">graph</a></li><li><a href="#structfield.id" title="id">id</a></li><li><a href="#structfield.mailbox" title="mailbox">mailbox</a></li></ul><h3><a href="#implementations">Methods</a></h3><ul class="block method"><li><a href="#method.init" title="init">init</a></li><li><a href="#method.run_loop" title="run_loop">run_loop</a></li></ul><h3><a href="#synthetic-implementations">Auto Trait Implementations</a></h3><ul class="block synthetic-implementation"><li><a href="#impl-Freeze-for-CHORUSAgent" title="!Freeze">!Freeze</a></li><li><a href="#impl-RefUnwindSafe-for-CHORUSAgent" title="!RefUnwindSafe">!RefUnwindSafe</a></li><li><a href="#impl-Sync-for-CHORUSAgent" title="!Sync">!Sync</a></li><li><a href="#impl-UnwindSafe-for-CHORUSAgent" title="!UnwindSafe">!UnwindSafe</a></li><li><a href="#impl-Send-for-CHORUSAgent" title="Send">Send</a></li><li><a href="#impl-Unpin-for-CHORUSAgent" title="Unpin">Unpin</a></li></ul><h3><a href="#blanket-implementations">Blanket Implementations</a></h3><ul class="block blanket-implementation"><li><a href="#impl-Any-for-T" title="Any">Any</a></li><li><a href="#impl-Borrow%3CT%3E-for-T" title="Borrow<T>">Borrow<T></a></li><li><a href="#impl-BorrowMut%3CT%3E-for-T" title="BorrowMut<T>">BorrowMut<T></a></li><li><a href="#impl-From%3CT%3E-for-T" title="From<T>">From<T></a></li><li><a href="#impl-Into%3CU%3E-for-T" title="Into<U>">Into<U></a></li><li><a href="#impl-TryFrom%3CU%3E-for-T" title="TryFrom<U>">TryFrom<U></a></li><li><a href="#impl-TryInto%3CU%3E-for-T" title="TryInto<U>">TryInto<U></a></li></ul></section><div id="rustdoc-modnav"><h2 class="in-crate"><a href="index.html">In crate chrs_<wbr>agent</a></h2></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><div class="rustdoc-breadcrumbs"><a href="index.html">chrs_agent</a></div><h1>Struct <span class="struct">CHORUSAgent</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/chrs_agent/main.rs.html#28-32">Source</a> </span></div><pre class="rust item-decl"><code>pub struct CHORUSAgent {
|
||||
pub(crate) id: <a class="struct" href="https://doc.rust-lang.org/1.87.0/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>,
|
||||
pub(crate) mailbox: <a class="struct" href="../chrs_mail/struct.Mailbox.html" title="struct chrs_mail::Mailbox">Mailbox</a>,
|
||||
pub(crate) graph: <a class="struct" href="../chrs_graph/struct.DoltGraph.html" title="struct chrs_graph::DoltGraph">DoltGraph</a>,
|
||||
}</code></pre><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Represents a running CHORUS agent.</p>
|
||||
<h2 id="fields-1"><a class="doc-anchor" href="#fields-1">§</a>Fields</h2>
|
||||
<ul>
|
||||
<li><code>id</code> – Logical identifier for the agent (e.g., “agent-001”).</li>
|
||||
<li><code>mailbox</code> – The <code>Mailbox</code> used for inter‑agent communication.</li>
|
||||
<li><code>graph</code> – Persistence layer (<code>DoltGraph</code>) where task logs are stored.</li>
|
||||
</ul>
|
||||
<h2 id="rationale"><a class="doc-anchor" href="#rationale">§</a>Rationale</h2>
|
||||
<p>Agents are isolated units of work. By keeping a dedicated mailbox and a graph
|
||||
per agent we guarantee that each agent can be started, stopped, and reasoned
|
||||
about independently while still contributing to the global CHORUS state.</p>
|
||||
</div></details><h2 id="fields" class="fields section-header">Fields<a href="#fields" class="anchor">§</a></h2><span id="structfield.id" class="structfield section-header"><a href="#structfield.id" class="anchor field">§</a><code>id: <a class="struct" href="https://doc.rust-lang.org/1.87.0/alloc/string/struct.String.html" title="struct alloc::string::String">String</a></code></span><span id="structfield.mailbox" class="structfield section-header"><a href="#structfield.mailbox" class="anchor field">§</a><code>mailbox: <a class="struct" href="../chrs_mail/struct.Mailbox.html" title="struct chrs_mail::Mailbox">Mailbox</a></code></span><span id="structfield.graph" class="structfield section-header"><a href="#structfield.graph" class="anchor field">§</a><code>graph: <a class="struct" href="../chrs_graph/struct.DoltGraph.html" title="struct chrs_graph::DoltGraph">DoltGraph</a></code></span><h2 id="implementations" class="section-header">Implementations<a href="#implementations" class="anchor">§</a></h2><div id="implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-CHORUSAgent" class="impl"><a class="src rightside" href="../src/chrs_agent/main.rs.html#34-98">Source</a><a href="#impl-CHORUSAgent" class="anchor">§</a><h3 class="code-header">impl <a class="struct" href="struct.CHORUSAgent.html" title="struct chrs_agent::CHORUSAgent">CHORUSAgent</a></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.init" class="method"><a class="src rightside" href="../src/chrs_agent/main.rs.html#47-64">Source</a><h4 class="code-header">pub(crate) async fn <a href="#method.init" class="fn">init</a>(
|
||||
id: &<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.str.html">str</a>,
|
||||
base_path: &<a class="struct" href="https://doc.rust-lang.org/1.87.0/std/path/struct.Path.html" title="struct std::path::Path">Path</a>,
|
||||
) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><Self, <a class="struct" href="https://doc.rust-lang.org/1.87.0/alloc/boxed/struct.Box.html" title="struct alloc::boxed::Box">Box</a><dyn <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/error/trait.Error.html" title="trait core::error::Error">Error</a>>></h4></section></summary><div class="docblock"><p>Initializes a new <code>CHORUSAgent</code>.</p>
|
||||
<p>This creates the filesystem layout under <code>base_path</code>, opens or creates the
|
||||
SQLite mailbox, and initialises a <code>DoltGraph</code> for state persistence.
|
||||
It also ensures that a <code>task_log</code> table exists for recording incoming
|
||||
messages.</p>
|
||||
<h5 id="parameters"><a class="doc-anchor" href="#parameters">§</a>Parameters</h5>
|
||||
<ul>
|
||||
<li><code>id</code> – Identifier for the agent instance.</li>
|
||||
<li><code>base_path</code> – Directory where the agent stores its data.</li>
|
||||
</ul>
|
||||
<p>Returns an instance ready to run its event loop.</p>
|
||||
</div></details><details class="toggle method-toggle" open><summary><section id="method.run_loop" class="method"><a class="src rightside" href="../src/chrs_agent/main.rs.html#72-97">Source</a><h4 class="code-header">pub(crate) async fn <a href="#method.run_loop" class="fn">run_loop</a>(&self)</h4></section></summary><div class="docblock"><p>Main event loop of the agent.</p>
|
||||
<p>It repeatedly polls the mailbox for pending messages addressed to this
|
||||
agent, logs each message into the <code>task_log</code> table, commits the graph, and
|
||||
acknowledges the message. The loop sleeps for a configurable interval to
|
||||
avoid busy‑waiting.</p>
|
||||
</div></details></div></details></div><h2 id="synthetic-implementations" class="section-header">Auto Trait Implementations<a href="#synthetic-implementations" class="anchor">§</a></h2><div id="synthetic-implementations-list"><section id="impl-Freeze-for-CHORUSAgent" class="impl"><a href="#impl-Freeze-for-CHORUSAgent" class="anchor">§</a><h3 class="code-header">impl !<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Freeze.html" title="trait core::marker::Freeze">Freeze</a> for <a class="struct" href="struct.CHORUSAgent.html" title="struct chrs_agent::CHORUSAgent">CHORUSAgent</a></h3></section><section id="impl-RefUnwindSafe-for-CHORUSAgent" class="impl"><a href="#impl-RefUnwindSafe-for-CHORUSAgent" class="anchor">§</a><h3 class="code-header">impl !<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/panic/unwind_safe/trait.RefUnwindSafe.html" title="trait core::panic::unwind_safe::RefUnwindSafe">RefUnwindSafe</a> for <a class="struct" href="struct.CHORUSAgent.html" title="struct chrs_agent::CHORUSAgent">CHORUSAgent</a></h3></section><section id="impl-Send-for-CHORUSAgent" class="impl"><a href="#impl-Send-for-CHORUSAgent" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Send.html" title="trait core::marker::Send">Send</a> for <a class="struct" href="struct.CHORUSAgent.html" title="struct chrs_agent::CHORUSAgent">CHORUSAgent</a></h3></section><section id="impl-Sync-for-CHORUSAgent" class="impl"><a href="#impl-Sync-for-CHORUSAgent" class="anchor">§</a><h3 class="code-header">impl !<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sync.html" title="trait core::marker::Sync">Sync</a> for <a class="struct" href="struct.CHORUSAgent.html" title="struct chrs_agent::CHORUSAgent">CHORUSAgent</a></h3></section><section id="impl-Unpin-for-CHORUSAgent" class="impl"><a href="#impl-Unpin-for-CHORUSAgent" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Unpin.html" title="trait core::marker::Unpin">Unpin</a> for <a class="struct" href="struct.CHORUSAgent.html" title="struct chrs_agent::CHORUSAgent">CHORUSAgent</a></h3></section><section id="impl-UnwindSafe-for-CHORUSAgent" class="impl"><a href="#impl-UnwindSafe-for-CHORUSAgent" class="anchor">§</a><h3 class="code-header">impl !<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/panic/unwind_safe/trait.UnwindSafe.html" title="trait core::panic::unwind_safe::UnwindSafe">UnwindSafe</a> for <a class="struct" href="struct.CHORUSAgent.html" title="struct chrs_agent::CHORUSAgent">CHORUSAgent</a></h3></section></div><h2 id="blanket-implementations" class="section-header">Blanket Implementations<a href="#blanket-implementations" class="anchor">§</a></h2><div id="blanket-implementations-list"><details class="toggle implementors-toggle"><summary><section id="impl-Any-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/any.rs.html#138">Source</a><a href="#impl-Any-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html" title="trait core::any::Any">Any</a> for T<div class="where">where
|
||||
T: 'static + ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.type_id" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/any.rs.html#139">Source</a><a href="#method.type_id" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html#tymethod.type_id" class="fn">type_id</a>(&self) -> <a class="struct" href="https://doc.rust-lang.org/1.87.0/core/any/struct.TypeId.html" title="struct core::any::TypeId">TypeId</a></h4></section></summary><div class='docblock'>Gets the <code>TypeId</code> of <code>self</code>. <a href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html#tymethod.type_id">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-Borrow%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#209">Source</a><a href="#impl-Borrow%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html" title="trait core::borrow::Borrow">Borrow</a><T> for T<div class="where">where
|
||||
T: ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#211">Source</a><a href="#method.borrow" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html#tymethod.borrow" class="fn">borrow</a>(&self) -> <a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.reference.html">&T</a></h4></section></summary><div class='docblock'>Immutably borrows from an owned value. <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html#tymethod.borrow">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-BorrowMut%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#217">Source</a><a href="#impl-BorrowMut%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html" title="trait core::borrow::BorrowMut">BorrowMut</a><T> for T<div class="where">where
|
||||
T: ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow_mut" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#218">Source</a><a href="#method.borrow_mut" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html#tymethod.borrow_mut" class="fn">borrow_mut</a>(&mut self) -> <a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.reference.html">&mut T</a></h4></section></summary><div class='docblock'>Mutably borrows from an owned value. <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html#tymethod.borrow_mut">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-From%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#767">Source</a><a href="#impl-From%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T> for T</h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.from" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#770">Source</a><a href="#method.from" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html#tymethod.from" class="fn">from</a>(t: T) -> T</h4></section></summary><div class="docblock"><p>Returns the argument unchanged.</p>
|
||||
</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-Into%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#750-752">Source</a><a href="#impl-Into%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html" title="trait core::convert::Into">Into</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.into" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#760">Source</a><a href="#method.into" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html#tymethod.into" class="fn">into</a>(self) -> U</h4></section></summary><div class="docblock"><p>Calls <code>U::from(self)</code>.</p>
|
||||
<p>That is, this conversion is whatever the implementation of
|
||||
<code><a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T> for U</code> chooses to do.</p>
|
||||
</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-TryFrom%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#806-808">Source</a><a href="#impl-TryFrom%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html" title="trait core::convert::Into">Into</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle" open><summary><section id="associatedtype.Error-1" class="associatedtype trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#810">Source</a><a href="#associatedtype.Error-1" class="anchor">§</a><h4 class="code-header">type <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" class="associatedtype">Error</a> = <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/convert/enum.Infallible.html" title="enum core::convert::Infallible">Infallible</a></h4></section></summary><div class='docblock'>The type returned in the event of a conversion error.</div></details><details class="toggle method-toggle" open><summary><section id="method.try_from" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#813">Source</a><a href="#method.try_from" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#tymethod.try_from" class="fn">try_from</a>(value: U) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><T, <T as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><U>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a>></h4></section></summary><div class='docblock'>Performs the conversion.</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-TryInto%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#791-793">Source</a><a href="#impl-TryInto%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html" title="trait core::convert::TryInto">TryInto</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle" open><summary><section id="associatedtype.Error" class="associatedtype trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#795">Source</a><a href="#associatedtype.Error" class="anchor">§</a><h4 class="code-header">type <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html#associatedtype.Error" class="associatedtype">Error</a> = <U as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a></h4></section></summary><div class='docblock'>The type returned in the event of a conversion error.</div></details><details class="toggle method-toggle" open><summary><section id="method.try_into" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#798">Source</a><a href="#method.try_into" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html#tymethod.try_into" class="fn">try_into</a>(self) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><U, <U as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a>></h4></section></summary><div class='docblock'>Performs the conversion.</div></details></div></details></div></section></div></main></body></html>
|
||||
1
target/doc/chrs_bubble/all.html
Normal file
1
target/doc/chrs_bubble/all.html
Normal file
@@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="List of all items in this crate"><title>List of all items in this crate</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_bubble" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod sys"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_bubble/index.html">chrs_<wbr>bubble</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h3><a href="#structs">Crate Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li><li><a href="#enums" title="Enums">Enums</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><h1>List of all items</h1><h3 id="structs">Structs</h3><ul class="all-items"><li><a href="struct.ProvenanceGraph.html">ProvenanceGraph</a></li></ul><h3 id="enums">Enums</h3><ul class="all-items"><li><a href="enum.BubbleError.html">BubbleError</a></li><li><a href="enum.ProvenanceEdge.html">ProvenanceEdge</a></li></ul></section></div></main></body></html>
|
||||
30
target/doc/chrs_bubble/enum.BubbleError.html
Normal file
30
target/doc/chrs_bubble/enum.BubbleError.html
Normal file
File diff suppressed because one or more lines are too long
44
target/doc/chrs_bubble/enum.ProvenanceEdge.html
Normal file
44
target/doc/chrs_bubble/enum.ProvenanceEdge.html
Normal file
File diff suppressed because one or more lines are too long
2
target/doc/chrs_bubble/index.html
Normal file
2
target/doc/chrs_bubble/index.html
Normal file
@@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="API documentation for the Rust `chrs_bubble` crate."><title>chrs_bubble - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_bubble" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="../crates.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod crate"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_bubble/index.html">chrs_<wbr>bubble</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><ul class="block"><li><a id="all-types" href="all.html">All Items</a></li></ul><section id="rustdoc-toc"><h3><a href="#structs">Crate Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li><li><a href="#enums" title="Enums">Enums</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1>Crate <span>chrs_bubble</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/chrs_bubble/lib.rs.html#1-217">Source</a> </span></div><h2 id="structs" class="section-header">Structs<a href="#structs" class="anchor">§</a></h2><dl class="item-table"><dt><a class="struct" href="struct.ProvenanceGraph.html" title="struct chrs_bubble::ProvenanceGraph">Provenance<wbr>Graph</a></dt><dd>Core structure that maintains an in‑memory DAG of provenance nodes and a
|
||||
persistent <code>DoltGraph</code> backend.</dd></dl><h2 id="enums" class="section-header">Enums<a href="#enums" class="anchor">§</a></h2><dl class="item-table"><dt><a class="enum" href="enum.BubbleError.html" title="enum chrs_bubble::BubbleError">Bubble<wbr>Error</a></dt><dd>Errors that can arise when working with a <code>ProvenanceGraph</code>.</dd><dt><a class="enum" href="enum.ProvenanceEdge.html" title="enum chrs_bubble::ProvenanceEdge">Provenance<wbr>Edge</a></dt><dd>Represents the kind of relationship between two provenance nodes.</dd></dl></section></div></main></body></html>
|
||||
1
target/doc/chrs_bubble/sidebar-items.js
Normal file
1
target/doc/chrs_bubble/sidebar-items.js
Normal file
@@ -0,0 +1 @@
|
||||
window.SIDEBAR_ITEMS = {"enum":["BubbleError","ProvenanceEdge"],"struct":["ProvenanceGraph"]};
|
||||
70
target/doc/chrs_bubble/struct.ProvenanceGraph.html
Normal file
70
target/doc/chrs_bubble/struct.ProvenanceGraph.html
Normal file
@@ -0,0 +1,70 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Core structure that maintains an in‑memory DAG of provenance nodes and a persistent `DoltGraph` backend."><title>ProvenanceGraph in chrs_bubble - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_bubble" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="sidebar-items.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc struct"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_bubble/index.html">chrs_<wbr>bubble</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">Provenance<wbr>Graph</a></h2><h3><a href="#implementations">Methods</a></h3><ul class="block method"><li><a href="#method.new" title="new">new</a></li><li><a href="#method.record_link" title="record_link">record_link</a></li><li><a href="#method.record_node" title="record_node">record_node</a></li></ul><h3><a href="#synthetic-implementations">Auto Trait Implementations</a></h3><ul class="block synthetic-implementation"><li><a href="#impl-Freeze-for-ProvenanceGraph" title="Freeze">Freeze</a></li><li><a href="#impl-RefUnwindSafe-for-ProvenanceGraph" title="RefUnwindSafe">RefUnwindSafe</a></li><li><a href="#impl-Send-for-ProvenanceGraph" title="Send">Send</a></li><li><a href="#impl-Sync-for-ProvenanceGraph" title="Sync">Sync</a></li><li><a href="#impl-Unpin-for-ProvenanceGraph" title="Unpin">Unpin</a></li><li><a href="#impl-UnwindSafe-for-ProvenanceGraph" title="UnwindSafe">UnwindSafe</a></li></ul><h3><a href="#blanket-implementations">Blanket Implementations</a></h3><ul class="block blanket-implementation"><li><a href="#impl-Any-for-T" title="Any">Any</a></li><li><a href="#impl-Borrow%3CT%3E-for-T" title="Borrow<T>">Borrow<T></a></li><li><a href="#impl-BorrowMut%3CT%3E-for-T" title="BorrowMut<T>">BorrowMut<T></a></li><li><a href="#impl-From%3CT%3E-for-T" title="From<T>">From<T></a></li><li><a href="#impl-Into%3CU%3E-for-T" title="Into<U>">Into<U></a></li><li><a href="#impl-TryFrom%3CU%3E-for-T" title="TryFrom<U>">TryFrom<U></a></li><li><a href="#impl-TryInto%3CU%3E-for-T" title="TryInto<U>">TryInto<U></a></li></ul></section><div id="rustdoc-modnav"><h2 class="in-crate"><a href="index.html">In crate chrs_<wbr>bubble</a></h2></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><div class="rustdoc-breadcrumbs"><a href="index.html">chrs_bubble</a></div><h1>Struct <span class="struct">ProvenanceGraph</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/chrs_bubble/lib.rs.html#87-91">Source</a> </span></div><pre class="rust item-decl"><code>pub struct ProvenanceGraph { <span class="comment">/* private fields */</span> }</code></pre><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Core structure that maintains an in‑memory DAG of provenance nodes and a
|
||||
persistent <code>DoltGraph</code> backend.</p>
|
||||
<ul>
|
||||
<li><strong>WHAT</strong> – Holds:
|
||||
<ul>
|
||||
<li><code>persistence</code>: The Dolt‑based storage implementation.</li>
|
||||
<li><code>dag</code>: A <code>petgraph::DiGraph</code> where node payloads are UUIDs and edges are
|
||||
<code>ProvenanceEdge</code>s.</li>
|
||||
<li><code>node_map</code>: A fast lookup map from node UUID to the corresponding
|
||||
<code>petgraph::NodeIndex</code>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>HOW</strong> – Provides methods to create nodes (<code>record_node</code>) and edges
|
||||
(<code>record_link</code>). These methods insert into the in‑memory graph and then
|
||||
persist the data in Dolt tables using simple <code>INSERT</code> statements followed by
|
||||
a <code>commit</code>.</li>
|
||||
<li><strong>WHY</strong> – Separating the transient in‑memory representation from durable
|
||||
storage gives fast runtime queries while guaranteeing that the provenance
|
||||
graph can survive process restarts and be inspected via Dolt tools.</li>
|
||||
</ul>
|
||||
</div></details><h2 id="implementations" class="section-header">Implementations<a href="#implementations" class="anchor">§</a></h2><div id="implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-ProvenanceGraph" class="impl"><a class="src rightside" href="../src/chrs_bubble/lib.rs.html#93-190">Source</a><a href="#impl-ProvenanceGraph" class="anchor">§</a><h3 class="code-header">impl <a class="struct" href="struct.ProvenanceGraph.html" title="struct chrs_bubble::ProvenanceGraph">ProvenanceGraph</a></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.new" class="method"><a class="src rightside" href="../src/chrs_bubble/lib.rs.html#101-107">Source</a><h4 class="code-header">pub fn <a href="#method.new" class="fn">new</a>(persistence: <a class="struct" href="../chrs_graph/struct.DoltGraph.html" title="struct chrs_graph::DoltGraph">DoltGraph</a>) -> Self</h4></section></summary><div class="docblock"><p>Creates a new <code>ProvenanceGraph</code> backed by a pre‑initialised <code>DoltGraph</code>.</p>
|
||||
<ul>
|
||||
<li><strong>WHAT</strong> – Returns a fresh instance with empty in‑memory structures.</li>
|
||||
<li><strong>HOW</strong> – Stores the supplied <code>persistence</code> and constructs a new <code>DiGraph</code>
|
||||
and empty <code>HashMap</code>.</li>
|
||||
<li><strong>WHY</strong> – Allows callers to decide where the Dolt repository lives (e.g.
|
||||
a temporary directory for tests or a permanent location for production).</li>
|
||||
</ul>
|
||||
</div></details><details class="toggle method-toggle" open><summary><section id="method.record_node" class="method"><a class="src rightside" href="../src/chrs_bubble/lib.rs.html#118-140">Source</a><h4 class="code-header">pub fn <a href="#method.record_node" class="fn">record_node</a>(
|
||||
&mut self,
|
||||
id: <a class="struct" href="https://docs.rs/uuid/1.21.0/uuid/struct.Uuid.html" title="struct uuid::Uuid">Uuid</a>,
|
||||
address: &<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.str.html">str</a>,
|
||||
) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.unit.html">()</a>, <a class="enum" href="enum.BubbleError.html" title="enum chrs_bubble::BubbleError">BubbleError</a>></h4></section></summary><div class="docblock"><p>Records a provenance node with a unique <code>Uuid</code> and an associated address.</p>
|
||||
<ul>
|
||||
<li><strong>WHAT</strong> – Persists the node both in‑memory (<code>dag</code> + <code>node_map</code>) and in a
|
||||
Dolt table called <code>provenance_nodes</code>.</li>
|
||||
<li><strong>HOW</strong> – If the node does not already exist, it is added to the DAG and a
|
||||
row is inserted via <code>persistence.insert_node</code>. A commit is performed with a
|
||||
descriptive message.</li>
|
||||
<li><strong>WHY</strong> – Storing the address (typically a UCXL address) allows later
|
||||
resolution of where the artifact originated.</li>
|
||||
</ul>
|
||||
</div></details><details class="toggle method-toggle" open><summary><section id="method.record_link" class="method"><a class="src rightside" href="../src/chrs_bubble/lib.rs.html#153-189">Source</a><h4 class="code-header">pub fn <a href="#method.record_link" class="fn">record_link</a>(
|
||||
&mut self,
|
||||
source: <a class="struct" href="https://docs.rs/uuid/1.21.0/uuid/struct.Uuid.html" title="struct uuid::Uuid">Uuid</a>,
|
||||
target: <a class="struct" href="https://docs.rs/uuid/1.21.0/uuid/struct.Uuid.html" title="struct uuid::Uuid">Uuid</a>,
|
||||
edge: <a class="enum" href="enum.ProvenanceEdge.html" title="enum chrs_bubble::ProvenanceEdge">ProvenanceEdge</a>,
|
||||
) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.unit.html">()</a>, <a class="enum" href="enum.BubbleError.html" title="enum chrs_bubble::BubbleError">BubbleError</a>></h4></section></summary><div class="docblock"><p>Records a directed edge between two existing nodes.</p>
|
||||
<ul>
|
||||
<li><strong>WHAT</strong> – Adds an edge of type <code>ProvenanceEdge</code> to the DAG and stores a
|
||||
corresponding row in the <code>provenance_links</code> Dolt table.</li>
|
||||
<li><strong>HOW</strong> – Retrieves the <code>NodeIndex</code> for each UUID (erroring with
|
||||
<code>BubbleError::NodeNotFound</code> if missing), adds the edge to <code>dag</code>, then
|
||||
inserts a row containing a new link UUID, source/target IDs and the edge
|
||||
type as a string.</li>
|
||||
<li><strong>WHY</strong> – Persisting links allows the full provenance graph to be queried
|
||||
outside the process, while the in‑memory representation keeps runtime
|
||||
operations cheap.</li>
|
||||
</ul>
|
||||
</div></details></div></details></div><h2 id="synthetic-implementations" class="section-header">Auto Trait Implementations<a href="#synthetic-implementations" class="anchor">§</a></h2><div id="synthetic-implementations-list"><section id="impl-Freeze-for-ProvenanceGraph" class="impl"><a href="#impl-Freeze-for-ProvenanceGraph" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Freeze.html" title="trait core::marker::Freeze">Freeze</a> for <a class="struct" href="struct.ProvenanceGraph.html" title="struct chrs_bubble::ProvenanceGraph">ProvenanceGraph</a></h3></section><section id="impl-RefUnwindSafe-for-ProvenanceGraph" class="impl"><a href="#impl-RefUnwindSafe-for-ProvenanceGraph" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/panic/unwind_safe/trait.RefUnwindSafe.html" title="trait core::panic::unwind_safe::RefUnwindSafe">RefUnwindSafe</a> for <a class="struct" href="struct.ProvenanceGraph.html" title="struct chrs_bubble::ProvenanceGraph">ProvenanceGraph</a></h3></section><section id="impl-Send-for-ProvenanceGraph" class="impl"><a href="#impl-Send-for-ProvenanceGraph" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Send.html" title="trait core::marker::Send">Send</a> for <a class="struct" href="struct.ProvenanceGraph.html" title="struct chrs_bubble::ProvenanceGraph">ProvenanceGraph</a></h3></section><section id="impl-Sync-for-ProvenanceGraph" class="impl"><a href="#impl-Sync-for-ProvenanceGraph" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sync.html" title="trait core::marker::Sync">Sync</a> for <a class="struct" href="struct.ProvenanceGraph.html" title="struct chrs_bubble::ProvenanceGraph">ProvenanceGraph</a></h3></section><section id="impl-Unpin-for-ProvenanceGraph" class="impl"><a href="#impl-Unpin-for-ProvenanceGraph" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Unpin.html" title="trait core::marker::Unpin">Unpin</a> for <a class="struct" href="struct.ProvenanceGraph.html" title="struct chrs_bubble::ProvenanceGraph">ProvenanceGraph</a></h3></section><section id="impl-UnwindSafe-for-ProvenanceGraph" class="impl"><a href="#impl-UnwindSafe-for-ProvenanceGraph" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/panic/unwind_safe/trait.UnwindSafe.html" title="trait core::panic::unwind_safe::UnwindSafe">UnwindSafe</a> for <a class="struct" href="struct.ProvenanceGraph.html" title="struct chrs_bubble::ProvenanceGraph">ProvenanceGraph</a></h3></section></div><h2 id="blanket-implementations" class="section-header">Blanket Implementations<a href="#blanket-implementations" class="anchor">§</a></h2><div id="blanket-implementations-list"><details class="toggle implementors-toggle"><summary><section id="impl-Any-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/any.rs.html#138">Source</a><a href="#impl-Any-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html" title="trait core::any::Any">Any</a> for T<div class="where">where
|
||||
T: 'static + ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.type_id" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/any.rs.html#139">Source</a><a href="#method.type_id" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html#tymethod.type_id" class="fn">type_id</a>(&self) -> <a class="struct" href="https://doc.rust-lang.org/1.87.0/core/any/struct.TypeId.html" title="struct core::any::TypeId">TypeId</a></h4></section></summary><div class='docblock'>Gets the <code>TypeId</code> of <code>self</code>. <a href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html#tymethod.type_id">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-Borrow%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#209">Source</a><a href="#impl-Borrow%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html" title="trait core::borrow::Borrow">Borrow</a><T> for T<div class="where">where
|
||||
T: ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#211">Source</a><a href="#method.borrow" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html#tymethod.borrow" class="fn">borrow</a>(&self) -> <a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.reference.html">&T</a></h4></section></summary><div class='docblock'>Immutably borrows from an owned value. <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html#tymethod.borrow">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-BorrowMut%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#217">Source</a><a href="#impl-BorrowMut%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html" title="trait core::borrow::BorrowMut">BorrowMut</a><T> for T<div class="where">where
|
||||
T: ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow_mut" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#218">Source</a><a href="#method.borrow_mut" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html#tymethod.borrow_mut" class="fn">borrow_mut</a>(&mut self) -> <a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.reference.html">&mut T</a></h4></section></summary><div class='docblock'>Mutably borrows from an owned value. <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html#tymethod.borrow_mut">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-From%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#767">Source</a><a href="#impl-From%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T> for T</h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.from" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#770">Source</a><a href="#method.from" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html#tymethod.from" class="fn">from</a>(t: T) -> T</h4></section></summary><div class="docblock"><p>Returns the argument unchanged.</p>
|
||||
</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-Into%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#750-752">Source</a><a href="#impl-Into%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html" title="trait core::convert::Into">Into</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.into" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#760">Source</a><a href="#method.into" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html#tymethod.into" class="fn">into</a>(self) -> U</h4></section></summary><div class="docblock"><p>Calls <code>U::from(self)</code>.</p>
|
||||
<p>That is, this conversion is whatever the implementation of
|
||||
<code><a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T> for U</code> chooses to do.</p>
|
||||
</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-TryFrom%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#806-808">Source</a><a href="#impl-TryFrom%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html" title="trait core::convert::Into">Into</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle" open><summary><section id="associatedtype.Error-1" class="associatedtype trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#810">Source</a><a href="#associatedtype.Error-1" class="anchor">§</a><h4 class="code-header">type <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" class="associatedtype">Error</a> = <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/convert/enum.Infallible.html" title="enum core::convert::Infallible">Infallible</a></h4></section></summary><div class='docblock'>The type returned in the event of a conversion error.</div></details><details class="toggle method-toggle" open><summary><section id="method.try_from" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#813">Source</a><a href="#method.try_from" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#tymethod.try_from" class="fn">try_from</a>(value: U) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><T, <T as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><U>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a>></h4></section></summary><div class='docblock'>Performs the conversion.</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-TryInto%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#791-793">Source</a><a href="#impl-TryInto%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html" title="trait core::convert::TryInto">TryInto</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle" open><summary><section id="associatedtype.Error" class="associatedtype trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#795">Source</a><a href="#associatedtype.Error" class="anchor">§</a><h4 class="code-header">type <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html#associatedtype.Error" class="associatedtype">Error</a> = <U as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a></h4></section></summary><div class='docblock'>The type returned in the event of a conversion error.</div></details><details class="toggle method-toggle" open><summary><section id="method.try_into" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#798">Source</a><a href="#method.try_into" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html#tymethod.try_into" class="fn">try_into</a>(self) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><U, <U as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a>></h4></section></summary><div class='docblock'>Performs the conversion.</div></details></div></details></div></section></div></main></body></html>
|
||||
1
target/doc/chrs_graph/all.html
Normal file
1
target/doc/chrs_graph/all.html
Normal file
@@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="List of all items in this crate"><title>List of all items in this crate</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_graph" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod sys"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_graph/index.html">chrs_<wbr>graph</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h3><a href="#structs">Crate Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li><li><a href="#enums" title="Enums">Enums</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><h1>List of all items</h1><h3 id="structs">Structs</h3><ul class="all-items"><li><a href="struct.DoltGraph.html">DoltGraph</a></li></ul><h3 id="enums">Enums</h3><ul class="all-items"><li><a href="enum.GraphError.html">GraphError</a></li></ul></section></div></main></body></html>
|
||||
24
target/doc/chrs_graph/enum.GraphError.html
Normal file
24
target/doc/chrs_graph/enum.GraphError.html
Normal file
File diff suppressed because one or more lines are too long
2
target/doc/chrs_graph/index.html
Normal file
2
target/doc/chrs_graph/index.html
Normal file
@@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="chrs-graph library implementation using Dolt for graph persistence."><title>chrs_graph - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_graph" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="../crates.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod crate"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_graph/index.html">chrs_<wbr>graph</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><ul class="block"><li><a id="all-types" href="all.html">All Items</a></li></ul><section id="rustdoc-toc"><h3><a href="#structs">Crate Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li><li><a href="#enums" title="Enums">Enums</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1>Crate <span>chrs_graph</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/chrs_graph/lib.rs.html#1-167">Source</a> </span></div><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>chrs-graph library implementation using Dolt for graph persistence.</p>
|
||||
</div></details><h2 id="structs" class="section-header">Structs<a href="#structs" class="anchor">§</a></h2><dl class="item-table"><dt><a class="struct" href="struct.DoltGraph.html" title="struct chrs_graph::DoltGraph">Dolt<wbr>Graph</a></dt><dd>Wrapper around a Dolt repository that stores graph data.</dd></dl><h2 id="enums" class="section-header">Enums<a href="#enums" class="anchor">§</a></h2><dl class="item-table"><dt><a class="enum" href="enum.GraphError.html" title="enum chrs_graph::GraphError">Graph<wbr>Error</a></dt><dd>Enumeration of possible errors that can arise while interacting with the <code>DoltGraph</code>.</dd></dl></section></div></main></body></html>
|
||||
1
target/doc/chrs_graph/sidebar-items.js
Normal file
1
target/doc/chrs_graph/sidebar-items.js
Normal file
@@ -0,0 +1 @@
|
||||
window.SIDEBAR_ITEMS = {"enum":["GraphError"],"struct":["DoltGraph"]};
|
||||
41
target/doc/chrs_graph/struct.DoltGraph.html
Normal file
41
target/doc/chrs_graph/struct.DoltGraph.html
Normal file
@@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Wrapper around a Dolt repository that stores graph data."><title>DoltGraph in chrs_graph - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_graph" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="sidebar-items.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc struct"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_graph/index.html">chrs_<wbr>graph</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">Dolt<wbr>Graph</a></h2><h3><a href="#">Sections</a></h3><ul class="block top-toc"><li><a href="#architectural-rationale" title="Architectural Rationale">Architectural Rationale</a></li></ul><h3><a href="#fields">Fields</a></h3><ul class="block structfield"><li><a href="#structfield.repo_path" title="repo_path">repo_path</a></li></ul><h3><a href="#implementations">Methods</a></h3><ul class="block method"><li><a href="#method.commit" title="commit">commit</a></li><li><a href="#method.create_table" title="create_table">create_table</a></li><li><a href="#method.init" title="init">init</a></li><li><a href="#method.insert_node" title="insert_node">insert_node</a></li></ul><h3><a href="#synthetic-implementations">Auto Trait Implementations</a></h3><ul class="block synthetic-implementation"><li><a href="#impl-Freeze-for-DoltGraph" title="Freeze">Freeze</a></li><li><a href="#impl-RefUnwindSafe-for-DoltGraph" title="RefUnwindSafe">RefUnwindSafe</a></li><li><a href="#impl-Send-for-DoltGraph" title="Send">Send</a></li><li><a href="#impl-Sync-for-DoltGraph" title="Sync">Sync</a></li><li><a href="#impl-Unpin-for-DoltGraph" title="Unpin">Unpin</a></li><li><a href="#impl-UnwindSafe-for-DoltGraph" title="UnwindSafe">UnwindSafe</a></li></ul><h3><a href="#blanket-implementations">Blanket Implementations</a></h3><ul class="block blanket-implementation"><li><a href="#impl-Any-for-T" title="Any">Any</a></li><li><a href="#impl-Borrow%3CT%3E-for-T" title="Borrow<T>">Borrow<T></a></li><li><a href="#impl-BorrowMut%3CT%3E-for-T" title="BorrowMut<T>">BorrowMut<T></a></li><li><a href="#impl-From%3CT%3E-for-T" title="From<T>">From<T></a></li><li><a href="#impl-Into%3CU%3E-for-T" title="Into<U>">Into<U></a></li><li><a href="#impl-TryFrom%3CU%3E-for-T" title="TryFrom<U>">TryFrom<U></a></li><li><a href="#impl-TryInto%3CU%3E-for-T" title="TryInto<U>">TryInto<U></a></li></ul></section><div id="rustdoc-modnav"><h2 class="in-crate"><a href="index.html">In crate chrs_<wbr>graph</a></h2></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><div class="rustdoc-breadcrumbs"><a href="index.html">chrs_graph</a></div><h1>Struct <span class="struct">DoltGraph</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/chrs_graph/lib.rs.html#40-43">Source</a> </span></div><pre class="rust item-decl"><code>pub struct DoltGraph {
|
||||
pub repo_path: <a class="struct" href="https://doc.rust-lang.org/1.87.0/std/path/struct.PathBuf.html" title="struct std::path::PathBuf">PathBuf</a>,
|
||||
}</code></pre><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Wrapper around a Dolt repository that stores graph data.</p>
|
||||
<p>The <code>DoltGraph</code> type encapsulates a path to a Dolt repo and provides high‑level
|
||||
operations such as initializing the repo, committing changes, creating tables, and
|
||||
inserting nodes expressed as JSON objects.</p>
|
||||
<h2 id="architectural-rationale"><a class="doc-anchor" href="#architectural-rationale">§</a>Architectural Rationale</h2>
|
||||
<p>Dolt offers a Git‑like version‑controlled SQL database, which aligns well with CHORUS’s
|
||||
need for an immutable, query‑able history of graph mutations. By wrapping Dolt commands in
|
||||
this struct we isolate the rest of the codebase from the command‑line interface, making the
|
||||
graph layer portable and easier to test.</p>
|
||||
</div></details><h2 id="fields" class="fields section-header">Fields<a href="#fields" class="anchor">§</a></h2><span id="structfield.repo_path" class="structfield section-header"><a href="#structfield.repo_path" class="anchor field">§</a><code>repo_path: <a class="struct" href="https://doc.rust-lang.org/1.87.0/std/path/struct.PathBuf.html" title="struct std::path::PathBuf">PathBuf</a></code></span><div class="docblock"><p>Filesystem path to the root of the Dolt repository.</p>
|
||||
</div><h2 id="implementations" class="section-header">Implementations<a href="#implementations" class="anchor">§</a></h2><div id="implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-DoltGraph" class="impl"><a class="src rightside" href="../src/chrs_graph/lib.rs.html#45-150">Source</a><a href="#impl-DoltGraph" class="anchor">§</a><h3 class="code-header">impl <a class="struct" href="struct.DoltGraph.html" title="struct chrs_graph::DoltGraph">DoltGraph</a></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.init" class="method"><a class="src rightside" href="../src/chrs_graph/lib.rs.html#51-67">Source</a><h4 class="code-header">pub fn <a href="#method.init" class="fn">init</a>(path: &<a class="struct" href="https://doc.rust-lang.org/1.87.0/std/path/struct.Path.html" title="struct std::path::Path">Path</a>) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><Self, <a class="enum" href="enum.GraphError.html" title="enum chrs_graph::GraphError">GraphError</a>></h4></section></summary><div class="docblock"><p>Initialise (or open) a Dolt repository at the given <code>path</code>.</p>
|
||||
<p>If the directory does not already contain a <code>.dolt</code> sub‑directory, the function runs
|
||||
<code>dolt init</code> to create a new repository. Errors from the underlying command are wrapped in
|
||||
<code>GraphError::CommandFailed</code>.</p>
|
||||
</div></details><details class="toggle method-toggle" open><summary><section id="method.commit" class="method"><a class="src rightside" href="../src/chrs_graph/lib.rs.html#90-94">Source</a><h4 class="code-header">pub fn <a href="#method.commit" class="fn">commit</a>(&self, message: &<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.str.html">str</a>) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.unit.html">()</a>, <a class="enum" href="enum.GraphError.html" title="enum chrs_graph::GraphError">GraphError</a>></h4></section></summary><div class="docblock"><p>Stage all changes and commit them with the provided <code>message</code>.</p>
|
||||
<p>The method first runs <code>dolt add -A</code> to stage modifications, then <code>dolt commit -m</code>.
|
||||
Any failure in these steps propagates as a <code>GraphError</code>.</p>
|
||||
</div></details><details class="toggle method-toggle" open><summary><section id="method.create_table" class="method"><a class="src rightside" href="../src/chrs_graph/lib.rs.html#100-111">Source</a><h4 class="code-header">pub fn <a href="#method.create_table" class="fn">create_table</a>(
|
||||
&self,
|
||||
table_name: &<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.str.html">str</a>,
|
||||
schema: &<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.str.html">str</a>,
|
||||
) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.unit.html">()</a>, <a class="enum" href="enum.GraphError.html" title="enum chrs_graph::GraphError">GraphError</a>></h4></section></summary><div class="docblock"><p>Create a SQL table within the Dolt repository.</p>
|
||||
<p><code>schema</code> should be a comma‑separated column definition list (e.g., <code>"id INT PRIMARY KEY, name TEXT"</code>).
|
||||
If the table already exists, the function treats it as a no‑op and returns <code>Ok(())</code>.</p>
|
||||
</div></details><details class="toggle method-toggle" open><summary><section id="method.insert_node" class="method"><a class="src rightside" href="../src/chrs_graph/lib.rs.html#118-149">Source</a><h4 class="code-header">pub fn <a href="#method.insert_node" class="fn">insert_node</a>(&self, table: &<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.str.html">str</a>, data: <a class="enum" href="https://docs.rs/serde_json/1.0.149/serde_json/value/enum.Value.html" title="enum serde_json::value::Value">Value</a>) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.unit.html">()</a>, <a class="enum" href="enum.GraphError.html" title="enum chrs_graph::GraphError">GraphError</a>></h4></section></summary><div class="docblock"><p>Insert a node represented by a JSON object into the specified <code>table</code>.</p>
|
||||
<p>The JSON <code>data</code> must be an object where keys correspond to column names. Supported value
|
||||
types are strings, numbers, booleans, and null. Complex JSON structures are rejected because
|
||||
they cannot be directly mapped to SQL scalar columns.</p>
|
||||
</div></details></div></details></div><h2 id="synthetic-implementations" class="section-header">Auto Trait Implementations<a href="#synthetic-implementations" class="anchor">§</a></h2><div id="synthetic-implementations-list"><section id="impl-Freeze-for-DoltGraph" class="impl"><a href="#impl-Freeze-for-DoltGraph" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Freeze.html" title="trait core::marker::Freeze">Freeze</a> for <a class="struct" href="struct.DoltGraph.html" title="struct chrs_graph::DoltGraph">DoltGraph</a></h3></section><section id="impl-RefUnwindSafe-for-DoltGraph" class="impl"><a href="#impl-RefUnwindSafe-for-DoltGraph" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/panic/unwind_safe/trait.RefUnwindSafe.html" title="trait core::panic::unwind_safe::RefUnwindSafe">RefUnwindSafe</a> for <a class="struct" href="struct.DoltGraph.html" title="struct chrs_graph::DoltGraph">DoltGraph</a></h3></section><section id="impl-Send-for-DoltGraph" class="impl"><a href="#impl-Send-for-DoltGraph" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Send.html" title="trait core::marker::Send">Send</a> for <a class="struct" href="struct.DoltGraph.html" title="struct chrs_graph::DoltGraph">DoltGraph</a></h3></section><section id="impl-Sync-for-DoltGraph" class="impl"><a href="#impl-Sync-for-DoltGraph" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sync.html" title="trait core::marker::Sync">Sync</a> for <a class="struct" href="struct.DoltGraph.html" title="struct chrs_graph::DoltGraph">DoltGraph</a></h3></section><section id="impl-Unpin-for-DoltGraph" class="impl"><a href="#impl-Unpin-for-DoltGraph" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Unpin.html" title="trait core::marker::Unpin">Unpin</a> for <a class="struct" href="struct.DoltGraph.html" title="struct chrs_graph::DoltGraph">DoltGraph</a></h3></section><section id="impl-UnwindSafe-for-DoltGraph" class="impl"><a href="#impl-UnwindSafe-for-DoltGraph" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/panic/unwind_safe/trait.UnwindSafe.html" title="trait core::panic::unwind_safe::UnwindSafe">UnwindSafe</a> for <a class="struct" href="struct.DoltGraph.html" title="struct chrs_graph::DoltGraph">DoltGraph</a></h3></section></div><h2 id="blanket-implementations" class="section-header">Blanket Implementations<a href="#blanket-implementations" class="anchor">§</a></h2><div id="blanket-implementations-list"><details class="toggle implementors-toggle"><summary><section id="impl-Any-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/any.rs.html#138">Source</a><a href="#impl-Any-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html" title="trait core::any::Any">Any</a> for T<div class="where">where
|
||||
T: 'static + ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.type_id" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/any.rs.html#139">Source</a><a href="#method.type_id" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html#tymethod.type_id" class="fn">type_id</a>(&self) -> <a class="struct" href="https://doc.rust-lang.org/1.87.0/core/any/struct.TypeId.html" title="struct core::any::TypeId">TypeId</a></h4></section></summary><div class='docblock'>Gets the <code>TypeId</code> of <code>self</code>. <a href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html#tymethod.type_id">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-Borrow%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#209">Source</a><a href="#impl-Borrow%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html" title="trait core::borrow::Borrow">Borrow</a><T> for T<div class="where">where
|
||||
T: ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#211">Source</a><a href="#method.borrow" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html#tymethod.borrow" class="fn">borrow</a>(&self) -> <a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.reference.html">&T</a></h4></section></summary><div class='docblock'>Immutably borrows from an owned value. <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html#tymethod.borrow">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-BorrowMut%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#217">Source</a><a href="#impl-BorrowMut%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html" title="trait core::borrow::BorrowMut">BorrowMut</a><T> for T<div class="where">where
|
||||
T: ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow_mut" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#218">Source</a><a href="#method.borrow_mut" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html#tymethod.borrow_mut" class="fn">borrow_mut</a>(&mut self) -> <a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.reference.html">&mut T</a></h4></section></summary><div class='docblock'>Mutably borrows from an owned value. <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html#tymethod.borrow_mut">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-From%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#767">Source</a><a href="#impl-From%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T> for T</h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.from" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#770">Source</a><a href="#method.from" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html#tymethod.from" class="fn">from</a>(t: T) -> T</h4></section></summary><div class="docblock"><p>Returns the argument unchanged.</p>
|
||||
</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-Into%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#750-752">Source</a><a href="#impl-Into%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html" title="trait core::convert::Into">Into</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.into" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#760">Source</a><a href="#method.into" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html#tymethod.into" class="fn">into</a>(self) -> U</h4></section></summary><div class="docblock"><p>Calls <code>U::from(self)</code>.</p>
|
||||
<p>That is, this conversion is whatever the implementation of
|
||||
<code><a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T> for U</code> chooses to do.</p>
|
||||
</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-TryFrom%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#806-808">Source</a><a href="#impl-TryFrom%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html" title="trait core::convert::Into">Into</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle" open><summary><section id="associatedtype.Error-1" class="associatedtype trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#810">Source</a><a href="#associatedtype.Error-1" class="anchor">§</a><h4 class="code-header">type <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" class="associatedtype">Error</a> = <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/convert/enum.Infallible.html" title="enum core::convert::Infallible">Infallible</a></h4></section></summary><div class='docblock'>The type returned in the event of a conversion error.</div></details><details class="toggle method-toggle" open><summary><section id="method.try_from" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#813">Source</a><a href="#method.try_from" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#tymethod.try_from" class="fn">try_from</a>(value: U) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><T, <T as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><U>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a>></h4></section></summary><div class='docblock'>Performs the conversion.</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-TryInto%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#791-793">Source</a><a href="#impl-TryInto%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html" title="trait core::convert::TryInto">TryInto</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle" open><summary><section id="associatedtype.Error" class="associatedtype trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#795">Source</a><a href="#associatedtype.Error" class="anchor">§</a><h4 class="code-header">type <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html#associatedtype.Error" class="associatedtype">Error</a> = <U as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a></h4></section></summary><div class='docblock'>The type returned in the event of a conversion error.</div></details><details class="toggle method-toggle" open><summary><section id="method.try_into" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#798">Source</a><a href="#method.try_into" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html#tymethod.try_into" class="fn">try_into</a>(self) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><U, <U as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a>></h4></section></summary><div class='docblock'>Performs the conversion.</div></details></div></details></div></section></div></main></body></html>
|
||||
1
target/doc/chrs_mail/all.html
Normal file
1
target/doc/chrs_mail/all.html
Normal file
@@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="List of all items in this crate"><title>List of all items in this crate</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_mail" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod sys"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_mail/index.html">chrs_<wbr>mail</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h3><a href="#structs">Crate Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li><li><a href="#enums" title="Enums">Enums</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><h1>List of all items</h1><h3 id="structs">Structs</h3><ul class="all-items"><li><a href="struct.Mailbox.html">Mailbox</a></li><li><a href="struct.Message.html">Message</a></li></ul><h3 id="enums">Enums</h3><ul class="all-items"><li><a href="enum.MailError.html">MailError</a></li></ul></section></div></main></body></html>
|
||||
24
target/doc/chrs_mail/enum.MailError.html
Normal file
24
target/doc/chrs_mail/enum.MailError.html
Normal file
File diff suppressed because one or more lines are too long
2
target/doc/chrs_mail/index.html
Normal file
2
target/doc/chrs_mail/index.html
Normal file
@@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="chrs-mail library implementation"><title>chrs_mail - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_mail" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="../crates.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod crate"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_mail/index.html">chrs_<wbr>mail</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><ul class="block"><li><a id="all-types" href="all.html">All Items</a></li></ul><section id="rustdoc-toc"><h3><a href="#structs">Crate Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li><li><a href="#enums" title="Enums">Enums</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1>Crate <span>chrs_mail</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/chrs_mail/lib.rs.html#1-235">Source</a> </span></div><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>chrs-mail library implementation</p>
|
||||
</div></details><h2 id="structs" class="section-header">Structs<a href="#structs" class="anchor">§</a></h2><dl class="item-table"><dt><a class="struct" href="struct.Mailbox.html" title="struct chrs_mail::Mailbox">Mailbox</a></dt><dd>Wrapper around a SQLite connection providing mailbox‑style functionalities.</dd><dt><a class="struct" href="struct.Message.html" title="struct chrs_mail::Message">Message</a></dt><dd>Represents a mail message stored in the mailbox.</dd></dl><h2 id="enums" class="section-header">Enums<a href="#enums" class="anchor">§</a></h2><dl class="item-table"><dt><a class="enum" href="enum.MailError.html" title="enum chrs_mail::MailError">Mail<wbr>Error</a></dt><dd>Errors that can occur while using the <code>Mailbox</code>.</dd></dl></section></div></main></body></html>
|
||||
1
target/doc/chrs_mail/sidebar-items.js
Normal file
1
target/doc/chrs_mail/sidebar-items.js
Normal file
@@ -0,0 +1 @@
|
||||
window.SIDEBAR_ITEMS = {"enum":["MailError"],"struct":["Mailbox","Message"]};
|
||||
31
target/doc/chrs_mail/struct.Mailbox.html
Normal file
31
target/doc/chrs_mail/struct.Mailbox.html
Normal file
@@ -0,0 +1,31 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Wrapper around a SQLite connection providing mailbox‑style functionalities."><title>Mailbox in chrs_mail - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_mail" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="sidebar-items.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc struct"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_mail/index.html">chrs_<wbr>mail</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">Mailbox</a></h2><h3><a href="#">Sections</a></h3><ul class="block top-toc"><li><a href="#architectural-rationale" title="Architectural Rationale">Architectural Rationale</a></li></ul><h3><a href="#implementations">Methods</a></h3><ul class="block method"><li><a href="#method.mark_read" title="mark_read">mark_read</a></li><li><a href="#method.open" title="open">open</a></li><li><a href="#method.receive_pending" title="receive_pending">receive_pending</a></li><li><a href="#method.send" title="send">send</a></li></ul><h3><a href="#synthetic-implementations">Auto Trait Implementations</a></h3><ul class="block synthetic-implementation"><li><a href="#impl-Freeze-for-Mailbox" title="!Freeze">!Freeze</a></li><li><a href="#impl-RefUnwindSafe-for-Mailbox" title="!RefUnwindSafe">!RefUnwindSafe</a></li><li><a href="#impl-Sync-for-Mailbox" title="!Sync">!Sync</a></li><li><a href="#impl-UnwindSafe-for-Mailbox" title="!UnwindSafe">!UnwindSafe</a></li><li><a href="#impl-Send-for-Mailbox" title="Send">Send</a></li><li><a href="#impl-Unpin-for-Mailbox" title="Unpin">Unpin</a></li></ul><h3><a href="#blanket-implementations">Blanket Implementations</a></h3><ul class="block blanket-implementation"><li><a href="#impl-Any-for-T" title="Any">Any</a></li><li><a href="#impl-Borrow%3CT%3E-for-T" title="Borrow<T>">Borrow<T></a></li><li><a href="#impl-BorrowMut%3CT%3E-for-T" title="BorrowMut<T>">BorrowMut<T></a></li><li><a href="#impl-From%3CT%3E-for-T" title="From<T>">From<T></a></li><li><a href="#impl-Into%3CU%3E-for-T" title="Into<U>">Into<U></a></li><li><a href="#impl-TryFrom%3CU%3E-for-T" title="TryFrom<U>">TryFrom<U></a></li><li><a href="#impl-TryInto%3CU%3E-for-T" title="TryInto<U>">TryInto<U></a></li></ul></section><div id="rustdoc-modnav"><h2 class="in-crate"><a href="index.html">In crate chrs_<wbr>mail</a></h2></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><div class="rustdoc-breadcrumbs"><a href="index.html">chrs_mail</a></div><h1>Struct <span class="struct">Mailbox</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/chrs_mail/lib.rs.html#76-78">Source</a> </span></div><pre class="rust item-decl"><code>pub struct Mailbox { <span class="comment">/* private fields */</span> }</code></pre><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Wrapper around a SQLite connection providing mailbox‑style functionalities.</p>
|
||||
<p>The <code>Mailbox</code> abstracts a SQLite database that stores <code>Message</code> records. It offers a minimal
|
||||
API for opening/creating the DB, sending messages, receiving pending messages for a peer, and
|
||||
marking messages as read.</p>
|
||||
<h2 id="architectural-rationale"><a class="doc-anchor" href="#architectural-rationale">§</a>Architectural Rationale</h2>
|
||||
<p>Using SQLite (via <code>rusqlite</code>) provides a zero‑configuration, file‑based persistence layer that is
|
||||
portable across the various environments where CHORUS components may run. The wrapper isolates the
|
||||
rest of the codebase from raw SQL handling, ensuring a single place for schema evolution and error
|
||||
mapping.</p>
|
||||
</div></details><h2 id="implementations" class="section-header">Implementations<a href="#implementations" class="anchor">§</a></h2><div id="implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-Mailbox" class="impl"><a class="src rightside" href="../src/chrs_mail/lib.rs.html#80-193">Source</a><a href="#impl-Mailbox" class="anchor">§</a><h3 class="code-header">impl <a class="struct" href="struct.Mailbox.html" title="struct chrs_mail::Mailbox">Mailbox</a></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.open" class="method"><a class="src rightside" href="../src/chrs_mail/lib.rs.html#85-103">Source</a><h4 class="code-header">pub fn <a href="#method.open" class="fn">open</a><P: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.AsRef.html" title="trait core::convert::AsRef">AsRef</a><<a class="struct" href="https://doc.rust-lang.org/1.87.0/std/path/struct.Path.html" title="struct std::path::Path">Path</a>>>(path: P) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><Self, <a class="enum" href="enum.MailError.html" title="enum chrs_mail::MailError">MailError</a>></h4></section></summary><div class="docblock"><p>Open (or create) a mailbox database at <code>path</code>.</p>
|
||||
<p>The function creates the SQLite file if it does not exist, enables WAL mode for better
|
||||
concurrency, and ensures the <code>messages</code> table is present.</p>
|
||||
</div></details><details class="toggle method-toggle" open><summary><section id="method.send" class="method"><a class="src rightside" href="../src/chrs_mail/lib.rs.html#109-124">Source</a><h4 class="code-header">pub fn <a href="#method.send" class="fn">send</a>(&self, msg: &<a class="struct" href="struct.Message.html" title="struct chrs_mail::Message">Message</a>) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.unit.html">()</a>, <a class="enum" href="enum.MailError.html" title="enum chrs_mail::MailError">MailError</a>></h4></section></summary><div class="docblock"><p>Store a new message in the mailbox.</p>
|
||||
<p>The <code>payload</code> field is serialised to a JSON string before insertion. The <code>read_at</code> column is
|
||||
initialised to <code>NULL</code> because the message has not yet been consumed.</p>
|
||||
</div></details><details class="toggle method-toggle" open><summary><section id="method.receive_pending" class="method"><a class="src rightside" href="../src/chrs_mail/lib.rs.html#130-180">Source</a><h4 class="code-header">pub fn <a href="#method.receive_pending" class="fn">receive_pending</a>(&self, peer_id: &<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.str.html">str</a>) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="struct" href="https://doc.rust-lang.org/1.87.0/alloc/vec/struct.Vec.html" title="struct alloc::vec::Vec">Vec</a><<a class="struct" href="struct.Message.html" title="struct chrs_mail::Message">Message</a>>, <a class="enum" href="enum.MailError.html" title="enum chrs_mail::MailError">MailError</a>></h4></section></summary><div class="docblock"><p>Retrieve all unread messages addressed to <code>peer_id</code>.</p>
|
||||
<p>The query filters on <code>to_peer</code> and <code>read_at IS NULL</code>. Returned rows are transformed back into
|
||||
<code>Message</code> structs, parsing the UUID, JSON payload, and RFC3339 timestamps.</p>
|
||||
</div></details><details class="toggle method-toggle" open><summary><section id="method.mark_read" class="method"><a class="src rightside" href="../src/chrs_mail/lib.rs.html#185-192">Source</a><h4 class="code-header">pub fn <a href="#method.mark_read" class="fn">mark_read</a>(&self, msg_id: <a class="struct" href="https://docs.rs/uuid/1.21.0/uuid/struct.Uuid.html" title="struct uuid::Uuid">Uuid</a>) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.unit.html">()</a>, <a class="enum" href="enum.MailError.html" title="enum chrs_mail::MailError">MailError</a>></h4></section></summary><div class="docblock"><p>Mark a message as read by setting its <code>read_at</code> timestamp.</p>
|
||||
<p>The current UTC time is stored in the <code>read_at</code> column for the row with the matching <code>id</code>.</p>
|
||||
</div></details></div></details></div><h2 id="synthetic-implementations" class="section-header">Auto Trait Implementations<a href="#synthetic-implementations" class="anchor">§</a></h2><div id="synthetic-implementations-list"><section id="impl-Freeze-for-Mailbox" class="impl"><a href="#impl-Freeze-for-Mailbox" class="anchor">§</a><h3 class="code-header">impl !<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Freeze.html" title="trait core::marker::Freeze">Freeze</a> for <a class="struct" href="struct.Mailbox.html" title="struct chrs_mail::Mailbox">Mailbox</a></h3></section><section id="impl-RefUnwindSafe-for-Mailbox" class="impl"><a href="#impl-RefUnwindSafe-for-Mailbox" class="anchor">§</a><h3 class="code-header">impl !<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/panic/unwind_safe/trait.RefUnwindSafe.html" title="trait core::panic::unwind_safe::RefUnwindSafe">RefUnwindSafe</a> for <a class="struct" href="struct.Mailbox.html" title="struct chrs_mail::Mailbox">Mailbox</a></h3></section><section id="impl-Send-for-Mailbox" class="impl"><a href="#impl-Send-for-Mailbox" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Send.html" title="trait core::marker::Send">Send</a> for <a class="struct" href="struct.Mailbox.html" title="struct chrs_mail::Mailbox">Mailbox</a></h3></section><section id="impl-Sync-for-Mailbox" class="impl"><a href="#impl-Sync-for-Mailbox" class="anchor">§</a><h3 class="code-header">impl !<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sync.html" title="trait core::marker::Sync">Sync</a> for <a class="struct" href="struct.Mailbox.html" title="struct chrs_mail::Mailbox">Mailbox</a></h3></section><section id="impl-Unpin-for-Mailbox" class="impl"><a href="#impl-Unpin-for-Mailbox" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Unpin.html" title="trait core::marker::Unpin">Unpin</a> for <a class="struct" href="struct.Mailbox.html" title="struct chrs_mail::Mailbox">Mailbox</a></h3></section><section id="impl-UnwindSafe-for-Mailbox" class="impl"><a href="#impl-UnwindSafe-for-Mailbox" class="anchor">§</a><h3 class="code-header">impl !<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/panic/unwind_safe/trait.UnwindSafe.html" title="trait core::panic::unwind_safe::UnwindSafe">UnwindSafe</a> for <a class="struct" href="struct.Mailbox.html" title="struct chrs_mail::Mailbox">Mailbox</a></h3></section></div><h2 id="blanket-implementations" class="section-header">Blanket Implementations<a href="#blanket-implementations" class="anchor">§</a></h2><div id="blanket-implementations-list"><details class="toggle implementors-toggle"><summary><section id="impl-Any-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/any.rs.html#138">Source</a><a href="#impl-Any-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html" title="trait core::any::Any">Any</a> for T<div class="where">where
|
||||
T: 'static + ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.type_id" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/any.rs.html#139">Source</a><a href="#method.type_id" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html#tymethod.type_id" class="fn">type_id</a>(&self) -> <a class="struct" href="https://doc.rust-lang.org/1.87.0/core/any/struct.TypeId.html" title="struct core::any::TypeId">TypeId</a></h4></section></summary><div class='docblock'>Gets the <code>TypeId</code> of <code>self</code>. <a href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html#tymethod.type_id">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-Borrow%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#209">Source</a><a href="#impl-Borrow%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html" title="trait core::borrow::Borrow">Borrow</a><T> for T<div class="where">where
|
||||
T: ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#211">Source</a><a href="#method.borrow" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html#tymethod.borrow" class="fn">borrow</a>(&self) -> <a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.reference.html">&T</a></h4></section></summary><div class='docblock'>Immutably borrows from an owned value. <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html#tymethod.borrow">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-BorrowMut%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#217">Source</a><a href="#impl-BorrowMut%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html" title="trait core::borrow::BorrowMut">BorrowMut</a><T> for T<div class="where">where
|
||||
T: ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow_mut" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#218">Source</a><a href="#method.borrow_mut" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html#tymethod.borrow_mut" class="fn">borrow_mut</a>(&mut self) -> <a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.reference.html">&mut T</a></h4></section></summary><div class='docblock'>Mutably borrows from an owned value. <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html#tymethod.borrow_mut">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-From%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#767">Source</a><a href="#impl-From%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T> for T</h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.from" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#770">Source</a><a href="#method.from" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html#tymethod.from" class="fn">from</a>(t: T) -> T</h4></section></summary><div class="docblock"><p>Returns the argument unchanged.</p>
|
||||
</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-Into%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#750-752">Source</a><a href="#impl-Into%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html" title="trait core::convert::Into">Into</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.into" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#760">Source</a><a href="#method.into" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html#tymethod.into" class="fn">into</a>(self) -> U</h4></section></summary><div class="docblock"><p>Calls <code>U::from(self)</code>.</p>
|
||||
<p>That is, this conversion is whatever the implementation of
|
||||
<code><a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T> for U</code> chooses to do.</p>
|
||||
</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-TryFrom%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#806-808">Source</a><a href="#impl-TryFrom%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html" title="trait core::convert::Into">Into</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle" open><summary><section id="associatedtype.Error-1" class="associatedtype trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#810">Source</a><a href="#associatedtype.Error-1" class="anchor">§</a><h4 class="code-header">type <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" class="associatedtype">Error</a> = <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/convert/enum.Infallible.html" title="enum core::convert::Infallible">Infallible</a></h4></section></summary><div class='docblock'>The type returned in the event of a conversion error.</div></details><details class="toggle method-toggle" open><summary><section id="method.try_from" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#813">Source</a><a href="#method.try_from" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#tymethod.try_from" class="fn">try_from</a>(value: U) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><T, <T as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><U>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a>></h4></section></summary><div class='docblock'>Performs the conversion.</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-TryInto%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#791-793">Source</a><a href="#impl-TryInto%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html" title="trait core::convert::TryInto">TryInto</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle" open><summary><section id="associatedtype.Error" class="associatedtype trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#795">Source</a><a href="#associatedtype.Error" class="anchor">§</a><h4 class="code-header">type <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html#associatedtype.Error" class="associatedtype">Error</a> = <U as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a></h4></section></summary><div class='docblock'>The type returned in the event of a conversion error.</div></details><details class="toggle method-toggle" open><summary><section id="method.try_into" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#798">Source</a><a href="#method.try_into" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html#tymethod.try_into" class="fn">try_into</a>(self) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><U, <U as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a>></h4></section></summary><div class='docblock'>Performs the conversion.</div></details></div></details></div></section></div></main></body></html>
|
||||
46
target/doc/chrs_mail/struct.Message.html
Normal file
46
target/doc/chrs_mail/struct.Message.html
Normal file
File diff suppressed because one or more lines are too long
1
target/doc/chrs_poc/all.html
Normal file
1
target/doc/chrs_poc/all.html
Normal file
@@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="List of all items in this crate"><title>List of all items in this crate</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_poc" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod sys"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_poc/index.html">chrs_<wbr>poc</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h3><a href="#functions">Crate Items</a></h3><ul class="block"><li><a href="#functions" title="Functions">Functions</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><h1>List of all items</h1><h3 id="functions">Functions</h3><ul class="all-items"><li><a href="fn.main.html">main</a></li></ul></section></div></main></body></html>
|
||||
13
target/doc/chrs_poc/fn.main.html
Normal file
13
target/doc/chrs_poc/fn.main.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Entry point for the proof‑of‑concept binary."><title>main in chrs_poc - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_poc" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="sidebar-items.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc fn"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_poc/index.html">chrs_<wbr>poc</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><div class="rustdoc-breadcrumbs"><a href="index.html">chrs_poc</a></div><h1>Function <span class="fn">main</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/chrs_poc/main.rs.html#39-128">Source</a> </span></div><pre class="rust item-decl"><code>pub(crate) fn main() -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.unit.html">()</a>, <a class="struct" href="https://doc.rust-lang.org/1.87.0/alloc/boxed/struct.Box.html" title="struct alloc::boxed::Box">Box</a><dyn <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/error/trait.Error.html" title="trait core::error::Error">Error</a>>></code></pre><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Entry point for the proof‑of‑concept binary.</p>
|
||||
<p>The function performs the following high‑level steps, each documented inline:</p>
|
||||
<ol>
|
||||
<li>Sets up a temporary workspace.</li>
|
||||
<li>Initialises all required components.</li>
|
||||
<li>Simulates a client sending an audit task to an agent.</li>
|
||||
<li>Processes the task as the agent would, including secret scrubbing.</li>
|
||||
<li>Curates a <code>DecisionRecord</code> via the SLURP engine.</li>
|
||||
<li>Records provenance relationships in the BUBBLE graph.</li>
|
||||
<li>Prints a success banner and the path to the persisted Dolt state.</li>
|
||||
</ol>
|
||||
<p>Errors from any component propagate via <code>?</code> and are reported as a boxed error.</p>
|
||||
</div></details></section></div></main></body></html>
|
||||
1
target/doc/chrs_poc/index.html
Normal file
1
target/doc/chrs_poc/index.html
Normal file
@@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="API documentation for the Rust `chrs_poc` crate."><title>chrs_poc - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_poc" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="../crates.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod crate"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_poc/index.html">chrs_<wbr>poc</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><ul class="block"><li><a id="all-types" href="all.html">All Items</a></li></ul><section id="rustdoc-toc"><h3><a href="#functions">Crate Items</a></h3><ul class="block"><li><a href="#functions" title="Functions">Functions</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1>Crate <span>chrs_poc</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/chrs_poc/main.rs.html#1-128">Source</a> </span></div><h2 id="functions" class="section-header">Functions<a href="#functions" class="anchor">§</a></h2><dl class="item-table"><dt><a class="fn" href="fn.main.html" title="fn chrs_poc::main">main</a><span title="Restricted Visibility"> 🔒</span> </dt><dd>Entry point for the proof‑of‑concept binary.</dd></dl></section></div></main></body></html>
|
||||
1
target/doc/chrs_poc/sidebar-items.js
Normal file
1
target/doc/chrs_poc/sidebar-items.js
Normal file
@@ -0,0 +1 @@
|
||||
window.SIDEBAR_ITEMS = {"fn":["main"]};
|
||||
1
target/doc/chrs_shhh/all.html
Normal file
1
target/doc/chrs_shhh/all.html
Normal file
@@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="List of all items in this crate"><title>List of all items in this crate</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_shhh" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod sys"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_shhh/index.html">chrs_<wbr>shhh</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h3><a href="#structs">Crate Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><h1>List of all items</h1><h3 id="structs">Structs</h3><ul class="all-items"><li><a href="struct.RedactionRule.html">RedactionRule</a></li><li><a href="struct.SecretSentinel.html">SecretSentinel</a></li></ul></section></div></main></body></html>
|
||||
1
target/doc/chrs_shhh/index.html
Normal file
1
target/doc/chrs_shhh/index.html
Normal file
@@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="API documentation for the Rust `chrs_shhh` crate."><title>chrs_shhh - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_shhh" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="../crates.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod crate"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_shhh/index.html">chrs_<wbr>shhh</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><ul class="block"><li><a id="all-types" href="all.html">All Items</a></li></ul><section id="rustdoc-toc"><h3><a href="#structs">Crate Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1>Crate <span>chrs_shhh</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/chrs_shhh/lib.rs.html#1-138">Source</a> </span></div><h2 id="structs" class="section-header">Structs<a href="#structs" class="anchor">§</a></h2><dl class="item-table"><dt><a class="struct" href="struct.RedactionRule.html" title="struct chrs_shhh::RedactionRule">Redaction<wbr>Rule</a></dt><dd>Represents a single rule used to redact a secret.</dd><dt><a class="struct" href="struct.SecretSentinel.html" title="struct chrs_shhh::SecretSentinel">Secret<wbr>Sentinel</a></dt><dd>The main entry point for secret detection and redaction.</dd></dl></section></div></main></body></html>
|
||||
1
target/doc/chrs_shhh/sidebar-items.js
Normal file
1
target/doc/chrs_shhh/sidebar-items.js
Normal file
@@ -0,0 +1 @@
|
||||
window.SIDEBAR_ITEMS = {"struct":["RedactionRule","SecretSentinel"]};
|
||||
29
target/doc/chrs_shhh/struct.RedactionRule.html
Normal file
29
target/doc/chrs_shhh/struct.RedactionRule.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Represents a single rule used to redact a secret."><title>RedactionRule in chrs_shhh - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_shhh" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="sidebar-items.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc struct"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_shhh/index.html">chrs_<wbr>shhh</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">Redaction<wbr>Rule</a></h2><h3><a href="#fields">Fields</a></h3><ul class="block structfield"><li><a href="#structfield.name" title="name">name</a></li><li><a href="#structfield.pattern" title="pattern">pattern</a></li><li><a href="#structfield.replacement" title="replacement">replacement</a></li></ul><h3><a href="#synthetic-implementations">Auto Trait Implementations</a></h3><ul class="block synthetic-implementation"><li><a href="#impl-Freeze-for-RedactionRule" title="Freeze">Freeze</a></li><li><a href="#impl-RefUnwindSafe-for-RedactionRule" title="RefUnwindSafe">RefUnwindSafe</a></li><li><a href="#impl-Send-for-RedactionRule" title="Send">Send</a></li><li><a href="#impl-Sync-for-RedactionRule" title="Sync">Sync</a></li><li><a href="#impl-Unpin-for-RedactionRule" title="Unpin">Unpin</a></li><li><a href="#impl-UnwindSafe-for-RedactionRule" title="UnwindSafe">UnwindSafe</a></li></ul><h3><a href="#blanket-implementations">Blanket Implementations</a></h3><ul class="block blanket-implementation"><li><a href="#impl-Any-for-T" title="Any">Any</a></li><li><a href="#impl-Borrow%3CT%3E-for-T" title="Borrow<T>">Borrow<T></a></li><li><a href="#impl-BorrowMut%3CT%3E-for-T" title="BorrowMut<T>">BorrowMut<T></a></li><li><a href="#impl-From%3CT%3E-for-T" title="From<T>">From<T></a></li><li><a href="#impl-Into%3CU%3E-for-T" title="Into<U>">Into<U></a></li><li><a href="#impl-TryFrom%3CU%3E-for-T" title="TryFrom<U>">TryFrom<U></a></li><li><a href="#impl-TryInto%3CU%3E-for-T" title="TryInto<U>">TryInto<U></a></li></ul></section><div id="rustdoc-modnav"><h2 class="in-crate"><a href="index.html">In crate chrs_<wbr>shhh</a></h2></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><div class="rustdoc-breadcrumbs"><a href="index.html">chrs_shhh</a></div><h1>Struct <span class="struct">RedactionRule</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/chrs_shhh/lib.rs.html#22-29">Source</a> </span></div><pre class="rust item-decl"><code>pub struct RedactionRule {
|
||||
pub name: <a class="struct" href="https://doc.rust-lang.org/1.87.0/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>,
|
||||
pub pattern: Regex,
|
||||
pub replacement: <a class="struct" href="https://doc.rust-lang.org/1.87.0/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>,
|
||||
}</code></pre><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Represents a single rule used to redact a secret.</p>
|
||||
<ul>
|
||||
<li><strong>WHAT</strong> – The name of the rule (e.g. “OpenAI API Key”), the compiled
|
||||
regular‑expression pattern that matches the secret, and the replacement string
|
||||
that will be inserted.</li>
|
||||
<li><strong>HOW</strong> – The <code>pattern</code> is a <code>Regex</code> that is applied to an input string. When a
|
||||
match is found the <code>replacement</code> is inserted using <code>replace_all</code>.</li>
|
||||
<li><strong>WHY</strong> – Decoupling the rule definition from the redaction logic makes the
|
||||
sanitizer extensible; new patterns can be added without changing the core
|
||||
implementation.</li>
|
||||
</ul>
|
||||
</div></details><h2 id="fields" class="fields section-header">Fields<a href="#fields" class="anchor">§</a></h2><span id="structfield.name" class="structfield section-header"><a href="#structfield.name" class="anchor field">§</a><code>name: <a class="struct" href="https://doc.rust-lang.org/1.87.0/alloc/string/struct.String.html" title="struct alloc::string::String">String</a></code></span><div class="docblock"><p>Human‑readable name for the rule.</p>
|
||||
</div><span id="structfield.pattern" class="structfield section-header"><a href="#structfield.pattern" class="anchor field">§</a><code>pattern: Regex</code></span><div class="docblock"><p>Compiled regular expression that matches the secret.</p>
|
||||
</div><span id="structfield.replacement" class="structfield section-header"><a href="#structfield.replacement" class="anchor field">§</a><code>replacement: <a class="struct" href="https://doc.rust-lang.org/1.87.0/alloc/string/struct.String.html" title="struct alloc::string::String">String</a></code></span><div class="docblock"><p>Text that will replace the matched secret.</p>
|
||||
</div><h2 id="synthetic-implementations" class="section-header">Auto Trait Implementations<a href="#synthetic-implementations" class="anchor">§</a></h2><div id="synthetic-implementations-list"><section id="impl-Freeze-for-RedactionRule" class="impl"><a href="#impl-Freeze-for-RedactionRule" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Freeze.html" title="trait core::marker::Freeze">Freeze</a> for <a class="struct" href="struct.RedactionRule.html" title="struct chrs_shhh::RedactionRule">RedactionRule</a></h3></section><section id="impl-RefUnwindSafe-for-RedactionRule" class="impl"><a href="#impl-RefUnwindSafe-for-RedactionRule" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/panic/unwind_safe/trait.RefUnwindSafe.html" title="trait core::panic::unwind_safe::RefUnwindSafe">RefUnwindSafe</a> for <a class="struct" href="struct.RedactionRule.html" title="struct chrs_shhh::RedactionRule">RedactionRule</a></h3></section><section id="impl-Send-for-RedactionRule" class="impl"><a href="#impl-Send-for-RedactionRule" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Send.html" title="trait core::marker::Send">Send</a> for <a class="struct" href="struct.RedactionRule.html" title="struct chrs_shhh::RedactionRule">RedactionRule</a></h3></section><section id="impl-Sync-for-RedactionRule" class="impl"><a href="#impl-Sync-for-RedactionRule" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sync.html" title="trait core::marker::Sync">Sync</a> for <a class="struct" href="struct.RedactionRule.html" title="struct chrs_shhh::RedactionRule">RedactionRule</a></h3></section><section id="impl-Unpin-for-RedactionRule" class="impl"><a href="#impl-Unpin-for-RedactionRule" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Unpin.html" title="trait core::marker::Unpin">Unpin</a> for <a class="struct" href="struct.RedactionRule.html" title="struct chrs_shhh::RedactionRule">RedactionRule</a></h3></section><section id="impl-UnwindSafe-for-RedactionRule" class="impl"><a href="#impl-UnwindSafe-for-RedactionRule" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/panic/unwind_safe/trait.UnwindSafe.html" title="trait core::panic::unwind_safe::UnwindSafe">UnwindSafe</a> for <a class="struct" href="struct.RedactionRule.html" title="struct chrs_shhh::RedactionRule">RedactionRule</a></h3></section></div><h2 id="blanket-implementations" class="section-header">Blanket Implementations<a href="#blanket-implementations" class="anchor">§</a></h2><div id="blanket-implementations-list"><details class="toggle implementors-toggle"><summary><section id="impl-Any-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/any.rs.html#138">Source</a><a href="#impl-Any-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html" title="trait core::any::Any">Any</a> for T<div class="where">where
|
||||
T: 'static + ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.type_id" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/any.rs.html#139">Source</a><a href="#method.type_id" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html#tymethod.type_id" class="fn">type_id</a>(&self) -> <a class="struct" href="https://doc.rust-lang.org/1.87.0/core/any/struct.TypeId.html" title="struct core::any::TypeId">TypeId</a></h4></section></summary><div class='docblock'>Gets the <code>TypeId</code> of <code>self</code>. <a href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html#tymethod.type_id">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-Borrow%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#209">Source</a><a href="#impl-Borrow%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html" title="trait core::borrow::Borrow">Borrow</a><T> for T<div class="where">where
|
||||
T: ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#211">Source</a><a href="#method.borrow" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html#tymethod.borrow" class="fn">borrow</a>(&self) -> <a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.reference.html">&T</a></h4></section></summary><div class='docblock'>Immutably borrows from an owned value. <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html#tymethod.borrow">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-BorrowMut%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#217">Source</a><a href="#impl-BorrowMut%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html" title="trait core::borrow::BorrowMut">BorrowMut</a><T> for T<div class="where">where
|
||||
T: ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow_mut" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#218">Source</a><a href="#method.borrow_mut" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html#tymethod.borrow_mut" class="fn">borrow_mut</a>(&mut self) -> <a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.reference.html">&mut T</a></h4></section></summary><div class='docblock'>Mutably borrows from an owned value. <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html#tymethod.borrow_mut">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-From%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#767">Source</a><a href="#impl-From%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T> for T</h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.from" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#770">Source</a><a href="#method.from" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html#tymethod.from" class="fn">from</a>(t: T) -> T</h4></section></summary><div class="docblock"><p>Returns the argument unchanged.</p>
|
||||
</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-Into%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#750-752">Source</a><a href="#impl-Into%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html" title="trait core::convert::Into">Into</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.into" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#760">Source</a><a href="#method.into" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html#tymethod.into" class="fn">into</a>(self) -> U</h4></section></summary><div class="docblock"><p>Calls <code>U::from(self)</code>.</p>
|
||||
<p>That is, this conversion is whatever the implementation of
|
||||
<code><a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T> for U</code> chooses to do.</p>
|
||||
</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-TryFrom%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#806-808">Source</a><a href="#impl-TryFrom%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html" title="trait core::convert::Into">Into</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle" open><summary><section id="associatedtype.Error-1" class="associatedtype trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#810">Source</a><a href="#associatedtype.Error-1" class="anchor">§</a><h4 class="code-header">type <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" class="associatedtype">Error</a> = <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/convert/enum.Infallible.html" title="enum core::convert::Infallible">Infallible</a></h4></section></summary><div class='docblock'>The type returned in the event of a conversion error.</div></details><details class="toggle method-toggle" open><summary><section id="method.try_from" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#813">Source</a><a href="#method.try_from" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#tymethod.try_from" class="fn">try_from</a>(value: U) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><T, <T as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><U>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a>></h4></section></summary><div class='docblock'>Performs the conversion.</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-TryInto%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#791-793">Source</a><a href="#impl-TryInto%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html" title="trait core::convert::TryInto">TryInto</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle" open><summary><section id="associatedtype.Error" class="associatedtype trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#795">Source</a><a href="#associatedtype.Error" class="anchor">§</a><h4 class="code-header">type <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html#associatedtype.Error" class="associatedtype">Error</a> = <U as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a></h4></section></summary><div class='docblock'>The type returned in the event of a conversion error.</div></details><details class="toggle method-toggle" open><summary><section id="method.try_into" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#798">Source</a><a href="#method.try_into" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html#tymethod.try_into" class="fn">try_into</a>(self) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><U, <U as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a>></h4></section></summary><div class='docblock'>Performs the conversion.</div></details></div></details></div></section></div></main></body></html>
|
||||
42
target/doc/chrs_shhh/struct.SecretSentinel.html
Normal file
42
target/doc/chrs_shhh/struct.SecretSentinel.html
Normal file
@@ -0,0 +1,42 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="The main entry point for secret detection and redaction."><title>SecretSentinel in chrs_shhh - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_shhh" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="sidebar-items.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc struct"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_shhh/index.html">chrs_<wbr>shhh</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">Secret<wbr>Sentinel</a></h2><h3><a href="#implementations">Methods</a></h3><ul class="block method"><li><a href="#method.contains_secrets" title="contains_secrets">contains_secrets</a></li><li><a href="#method.new_default" title="new_default">new_default</a></li><li><a href="#method.scrub_text" title="scrub_text">scrub_text</a></li></ul><h3><a href="#synthetic-implementations">Auto Trait Implementations</a></h3><ul class="block synthetic-implementation"><li><a href="#impl-Freeze-for-SecretSentinel" title="Freeze">Freeze</a></li><li><a href="#impl-RefUnwindSafe-for-SecretSentinel" title="RefUnwindSafe">RefUnwindSafe</a></li><li><a href="#impl-Send-for-SecretSentinel" title="Send">Send</a></li><li><a href="#impl-Sync-for-SecretSentinel" title="Sync">Sync</a></li><li><a href="#impl-Unpin-for-SecretSentinel" title="Unpin">Unpin</a></li><li><a href="#impl-UnwindSafe-for-SecretSentinel" title="UnwindSafe">UnwindSafe</a></li></ul><h3><a href="#blanket-implementations">Blanket Implementations</a></h3><ul class="block blanket-implementation"><li><a href="#impl-Any-for-T" title="Any">Any</a></li><li><a href="#impl-Borrow%3CT%3E-for-T" title="Borrow<T>">Borrow<T></a></li><li><a href="#impl-BorrowMut%3CT%3E-for-T" title="BorrowMut<T>">BorrowMut<T></a></li><li><a href="#impl-From%3CT%3E-for-T" title="From<T>">From<T></a></li><li><a href="#impl-Into%3CU%3E-for-T" title="Into<U>">Into<U></a></li><li><a href="#impl-TryFrom%3CU%3E-for-T" title="TryFrom<U>">TryFrom<U></a></li><li><a href="#impl-TryInto%3CU%3E-for-T" title="TryInto<U>">TryInto<U></a></li></ul></section><div id="rustdoc-modnav"><h2 class="in-crate"><a href="index.html">In crate chrs_<wbr>shhh</a></h2></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><div class="rustdoc-breadcrumbs"><a href="index.html">chrs_shhh</a></div><h1>Struct <span class="struct">SecretSentinel</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/chrs_shhh/lib.rs.html#38-40">Source</a> </span></div><pre class="rust item-decl"><code>pub struct SecretSentinel { <span class="comment">/* private fields */</span> }</code></pre><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>The main entry point for secret detection and redaction.</p>
|
||||
<ul>
|
||||
<li><strong>WHAT</strong> – Holds a collection of <code>RedactionRule</code>s.</li>
|
||||
<li><strong>HOW</strong> – Provides methods to scrub a string (<code>scrub_text</code>) and to simply
|
||||
check whether any secret is present (<code>contains_secrets</code>).</li>
|
||||
<li><strong>WHY</strong> – Centralising the rules in a struct enables reuse and makes testing
|
||||
straightforward.</li>
|
||||
</ul>
|
||||
</div></details><h2 id="implementations" class="section-header">Implementations<a href="#implementations" class="anchor">§</a></h2><div id="implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-SecretSentinel" class="impl"><a class="src rightside" href="../src/chrs_shhh/lib.rs.html#52-109">Source</a><a href="#impl-SecretSentinel" class="anchor">§</a><h3 class="code-header">impl <a class="struct" href="struct.SecretSentinel.html" title="struct chrs_shhh::SecretSentinel">SecretSentinel</a></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.new_default" class="method"><a class="src rightside" href="../src/chrs_shhh/lib.rs.html#61-81">Source</a><h4 class="code-header">pub fn <a href="#method.new_default" class="fn">new_default</a>() -> Self</h4></section></summary><div class="docblock"><p>Constructs a <code>SecretSentinel</code> pre‑populated with a sensible default set of rules.</p>
|
||||
<ul>
|
||||
<li><strong>WHAT</strong> – Returns a sentinel containing three rules: OpenAI, AWS and a generic
|
||||
secret matcher.</li>
|
||||
<li><strong>HOW</strong> – Instantiates <code>RedactionRule</code>s using the lazily‑initialised regexes
|
||||
above and stores them in the <code>rules</code> vector.</li>
|
||||
<li><strong>WHY</strong> – Provides a ready‑to‑use configuration for typical development
|
||||
environments while still allowing callers to create custom instances.</li>
|
||||
</ul>
|
||||
</div></details><details class="toggle method-toggle" open><summary><section id="method.scrub_text" class="method"><a class="src rightside" href="../src/chrs_shhh/lib.rs.html#89-98">Source</a><h4 class="code-header">pub fn <a href="#method.scrub_text" class="fn">scrub_text</a>(&self, input: &<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.str.html">str</a>) -> <a class="struct" href="https://doc.rust-lang.org/1.87.0/alloc/string/struct.String.html" title="struct alloc::string::String">String</a></h4></section></summary><div class="docblock"><p>Redacts all secrets found in <code>input</code> according to the configured rules.</p>
|
||||
<ul>
|
||||
<li><strong>WHAT</strong> – Returns a new <code>String</code> where each match has been replaced.</li>
|
||||
<li><strong>HOW</strong> – Iterates over the rules and applies <code>replace_all</code> for each.</li>
|
||||
<li><strong>WHY</strong> – Performing the replacements sequentially ensures that overlapping
|
||||
patterns are handled deterministically.</li>
|
||||
</ul>
|
||||
</div></details><details class="toggle method-toggle" open><summary><section id="method.contains_secrets" class="method"><a class="src rightside" href="../src/chrs_shhh/lib.rs.html#106-108">Source</a><h4 class="code-header">pub fn <a href="#method.contains_secrets" class="fn">contains_secrets</a>(&self, input: &<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.str.html">str</a>) -> <a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.bool.html">bool</a></h4></section></summary><div class="docblock"><p>Checks whether any of the configured rules match <code>input</code>.</p>
|
||||
<ul>
|
||||
<li><strong>WHAT</strong> – Returns <code>true</code> if at least one rule’s pattern matches.</li>
|
||||
<li><strong>HOW</strong> – Uses <code>Iter::any</code> over <code>self.rules</code> with <code>is_match</code>.</li>
|
||||
<li><strong>WHY</strong> – A quick predicate useful for short‑circuiting logging or error
|
||||
handling before performing the full redaction.</li>
|
||||
</ul>
|
||||
</div></details></div></details></div><h2 id="synthetic-implementations" class="section-header">Auto Trait Implementations<a href="#synthetic-implementations" class="anchor">§</a></h2><div id="synthetic-implementations-list"><section id="impl-Freeze-for-SecretSentinel" class="impl"><a href="#impl-Freeze-for-SecretSentinel" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Freeze.html" title="trait core::marker::Freeze">Freeze</a> for <a class="struct" href="struct.SecretSentinel.html" title="struct chrs_shhh::SecretSentinel">SecretSentinel</a></h3></section><section id="impl-RefUnwindSafe-for-SecretSentinel" class="impl"><a href="#impl-RefUnwindSafe-for-SecretSentinel" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/panic/unwind_safe/trait.RefUnwindSafe.html" title="trait core::panic::unwind_safe::RefUnwindSafe">RefUnwindSafe</a> for <a class="struct" href="struct.SecretSentinel.html" title="struct chrs_shhh::SecretSentinel">SecretSentinel</a></h3></section><section id="impl-Send-for-SecretSentinel" class="impl"><a href="#impl-Send-for-SecretSentinel" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Send.html" title="trait core::marker::Send">Send</a> for <a class="struct" href="struct.SecretSentinel.html" title="struct chrs_shhh::SecretSentinel">SecretSentinel</a></h3></section><section id="impl-Sync-for-SecretSentinel" class="impl"><a href="#impl-Sync-for-SecretSentinel" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sync.html" title="trait core::marker::Sync">Sync</a> for <a class="struct" href="struct.SecretSentinel.html" title="struct chrs_shhh::SecretSentinel">SecretSentinel</a></h3></section><section id="impl-Unpin-for-SecretSentinel" class="impl"><a href="#impl-Unpin-for-SecretSentinel" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Unpin.html" title="trait core::marker::Unpin">Unpin</a> for <a class="struct" href="struct.SecretSentinel.html" title="struct chrs_shhh::SecretSentinel">SecretSentinel</a></h3></section><section id="impl-UnwindSafe-for-SecretSentinel" class="impl"><a href="#impl-UnwindSafe-for-SecretSentinel" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/panic/unwind_safe/trait.UnwindSafe.html" title="trait core::panic::unwind_safe::UnwindSafe">UnwindSafe</a> for <a class="struct" href="struct.SecretSentinel.html" title="struct chrs_shhh::SecretSentinel">SecretSentinel</a></h3></section></div><h2 id="blanket-implementations" class="section-header">Blanket Implementations<a href="#blanket-implementations" class="anchor">§</a></h2><div id="blanket-implementations-list"><details class="toggle implementors-toggle"><summary><section id="impl-Any-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/any.rs.html#138">Source</a><a href="#impl-Any-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html" title="trait core::any::Any">Any</a> for T<div class="where">where
|
||||
T: 'static + ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.type_id" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/any.rs.html#139">Source</a><a href="#method.type_id" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html#tymethod.type_id" class="fn">type_id</a>(&self) -> <a class="struct" href="https://doc.rust-lang.org/1.87.0/core/any/struct.TypeId.html" title="struct core::any::TypeId">TypeId</a></h4></section></summary><div class='docblock'>Gets the <code>TypeId</code> of <code>self</code>. <a href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html#tymethod.type_id">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-Borrow%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#209">Source</a><a href="#impl-Borrow%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html" title="trait core::borrow::Borrow">Borrow</a><T> for T<div class="where">where
|
||||
T: ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#211">Source</a><a href="#method.borrow" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html#tymethod.borrow" class="fn">borrow</a>(&self) -> <a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.reference.html">&T</a></h4></section></summary><div class='docblock'>Immutably borrows from an owned value. <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html#tymethod.borrow">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-BorrowMut%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#217">Source</a><a href="#impl-BorrowMut%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html" title="trait core::borrow::BorrowMut">BorrowMut</a><T> for T<div class="where">where
|
||||
T: ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow_mut" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#218">Source</a><a href="#method.borrow_mut" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html#tymethod.borrow_mut" class="fn">borrow_mut</a>(&mut self) -> <a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.reference.html">&mut T</a></h4></section></summary><div class='docblock'>Mutably borrows from an owned value. <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html#tymethod.borrow_mut">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-From%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#767">Source</a><a href="#impl-From%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T> for T</h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.from" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#770">Source</a><a href="#method.from" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html#tymethod.from" class="fn">from</a>(t: T) -> T</h4></section></summary><div class="docblock"><p>Returns the argument unchanged.</p>
|
||||
</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-Into%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#750-752">Source</a><a href="#impl-Into%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html" title="trait core::convert::Into">Into</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.into" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#760">Source</a><a href="#method.into" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html#tymethod.into" class="fn">into</a>(self) -> U</h4></section></summary><div class="docblock"><p>Calls <code>U::from(self)</code>.</p>
|
||||
<p>That is, this conversion is whatever the implementation of
|
||||
<code><a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T> for U</code> chooses to do.</p>
|
||||
</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-TryFrom%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#806-808">Source</a><a href="#impl-TryFrom%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html" title="trait core::convert::Into">Into</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle" open><summary><section id="associatedtype.Error-1" class="associatedtype trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#810">Source</a><a href="#associatedtype.Error-1" class="anchor">§</a><h4 class="code-header">type <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" class="associatedtype">Error</a> = <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/convert/enum.Infallible.html" title="enum core::convert::Infallible">Infallible</a></h4></section></summary><div class='docblock'>The type returned in the event of a conversion error.</div></details><details class="toggle method-toggle" open><summary><section id="method.try_from" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#813">Source</a><a href="#method.try_from" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#tymethod.try_from" class="fn">try_from</a>(value: U) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><T, <T as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><U>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a>></h4></section></summary><div class='docblock'>Performs the conversion.</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-TryInto%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#791-793">Source</a><a href="#impl-TryInto%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html" title="trait core::convert::TryInto">TryInto</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle" open><summary><section id="associatedtype.Error" class="associatedtype trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#795">Source</a><a href="#associatedtype.Error" class="anchor">§</a><h4 class="code-header">type <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html#associatedtype.Error" class="associatedtype">Error</a> = <U as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a></h4></section></summary><div class='docblock'>The type returned in the event of a conversion error.</div></details><details class="toggle method-toggle" open><summary><section id="method.try_into" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#798">Source</a><a href="#method.try_into" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html#tymethod.try_into" class="fn">try_into</a>(self) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><U, <U as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a>></h4></section></summary><div class='docblock'>Performs the conversion.</div></details></div></details></div></section></div></main></body></html>
|
||||
1
target/doc/chrs_slurp/all.html
Normal file
1
target/doc/chrs_slurp/all.html
Normal file
@@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="List of all items in this crate"><title>List of all items in this crate</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_slurp" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod sys"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_slurp/index.html">chrs_<wbr>slurp</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h3><a href="#structs">Crate Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li><li><a href="#enums" title="Enums">Enums</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><h1>List of all items</h1><h3 id="structs">Structs</h3><ul class="all-items"><li><a href="struct.CurationEngine.html">CurationEngine</a></li><li><a href="struct.DecisionRecord.html">DecisionRecord</a></li></ul><h3 id="enums">Enums</h3><ul class="all-items"><li><a href="enum.SlurpError.html">SlurpError</a></li></ul></section></div></main></body></html>
|
||||
23
target/doc/chrs_slurp/enum.SlurpError.html
Normal file
23
target/doc/chrs_slurp/enum.SlurpError.html
Normal file
File diff suppressed because one or more lines are too long
34
target/doc/chrs_slurp/index.html
Normal file
34
target/doc/chrs_slurp/index.html
Normal file
@@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="chrs-slurp"><title>chrs_slurp - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_slurp" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="../crates.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod crate"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_slurp/index.html">chrs_<wbr>slurp</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><ul class="block"><li><a id="all-types" href="all.html">All Items</a></li></ul><section id="rustdoc-toc"><h3><a href="#">Sections</a></h3><ul class="block top-toc"><li><a href="#chrs-slurp" title="chrs-slurp">chrs-slurp</a><ul><li><a href="#architectural-rationale" title="Architectural Rationale">Architectural Rationale</a></li></ul></li><li><a href="#public-api" title="Public API">Public API</a></li></ul><h3><a href="#structs">Crate Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li><li><a href="#enums" title="Enums">Enums</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1>Crate <span>chrs_slurp</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/chrs_slurp/lib.rs.html#1-181">Source</a> </span></div><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><h2 id="chrs-slurp"><a class="doc-anchor" href="#chrs-slurp">§</a>chrs-slurp</h2>
|
||||
<p><strong>Intelligence Crate</strong> – Provides the <em>curation</em> layer for the CHORUS system.</p>
|
||||
<p>The purpose of this crate is to take <strong>Decision Records</strong> generated by autonomous
|
||||
agents, validate them, and persist them into the graph database. It isolates the
|
||||
validation and storage concerns so that other components (e.g. provenance, security)
|
||||
can work with a clean, audited data model.</p>
|
||||
<h3 id="architectural-rationale"><a class="doc-anchor" href="#architectural-rationale">§</a>Architectural Rationale</h3>
|
||||
<ul>
|
||||
<li><strong>Separation of concerns</strong> – Agents produce raw decisions; this crate is the
|
||||
single source of truth for how those decisions are stored.</li>
|
||||
<li><strong>Auditability</strong> – By persisting to a Dolt‑backed graph each decision is versioned
|
||||
and can be replay‑backed, satisfying CHORUS’s requirement for reproducible
|
||||
reasoning.</li>
|
||||
<li><strong>Extensibility</strong> – The <code>CurationEngine</code> can be extended with additional validation
|
||||
steps (e.g. policy checks) without touching the agents themselves.</li>
|
||||
</ul>
|
||||
<p>The crate depends on:</p>
|
||||
<ul>
|
||||
<li><code>chrs-graph</code> – a thin wrapper around a Dolt‑backed graph implementation.</li>
|
||||
<li><code>ucxl</code> – for addressing external knowledge artefacts.</li>
|
||||
<li><code>chrono</code>, <code>serde</code>, <code>uuid</code> – standard utilities for timestamps, (de)serialization
|
||||
and unique identifiers.</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<h2 id="public-api"><a class="doc-anchor" href="#public-api">§</a>Public API</h2>
|
||||
<p>The public surface consists of three items:</p>
|
||||
<ul>
|
||||
<li><code>DecisionRecord</code> – data structure representing a curated decision.</li>
|
||||
<li><code>SlurpError</code> – enumeration of possible errors while curating.</li>
|
||||
<li><code>CurationEngine</code> – the engine that validates and persists <code>DecisionRecord</code>s.</li>
|
||||
</ul>
|
||||
<p>Each item is documented in‑line below.</p>
|
||||
</div></details><h2 id="structs" class="section-header">Structs<a href="#structs" class="anchor">§</a></h2><dl class="item-table"><dt><a class="struct" href="struct.CurationEngine.html" title="struct chrs_slurp::CurationEngine">Curation<wbr>Engine</a></dt><dd>Core engine that validates and persists <code>DecisionRecord</code>s into the
|
||||
Dolt‑backed graph.</dd><dt><a class="struct" href="struct.DecisionRecord.html" title="struct chrs_slurp::DecisionRecord">Decision<wbr>Record</a></dt><dd>A record representing a curated decision within the CHORUS system.</dd></dl><h2 id="enums" class="section-header">Enums<a href="#enums" class="anchor">§</a></h2><dl class="item-table"><dt><a class="enum" href="enum.SlurpError.html" title="enum chrs_slurp::SlurpError">Slurp<wbr>Error</a></dt><dd>Errors that can arise while slurping (curating) a decision record.</dd></dl></section></div></main></body></html>
|
||||
1
target/doc/chrs_slurp/sidebar-items.js
Normal file
1
target/doc/chrs_slurp/sidebar-items.js
Normal file
@@ -0,0 +1 @@
|
||||
window.SIDEBAR_ITEMS = {"enum":["SlurpError"],"struct":["CurationEngine","DecisionRecord"]};
|
||||
36
target/doc/chrs_slurp/struct.CurationEngine.html
Normal file
36
target/doc/chrs_slurp/struct.CurationEngine.html
Normal file
@@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Core engine that validates and persists `DecisionRecord`s into the Dolt‑backed graph."><title>CurationEngine in chrs_slurp - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_slurp" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="sidebar-items.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc struct"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_slurp/index.html">chrs_<wbr>slurp</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">Curation<wbr>Engine</a></h2><h3><a href="#">Sections</a></h3><ul class="block top-toc"><li><a href="#why" title="Why">Why</a></li></ul><h3><a href="#implementations">Methods</a></h3><ul class="block method"><li><a href="#method.curate_decision" title="curate_decision">curate_decision</a></li><li><a href="#method.new" title="new">new</a></li></ul><h3><a href="#synthetic-implementations">Auto Trait Implementations</a></h3><ul class="block synthetic-implementation"><li><a href="#impl-Freeze-for-CurationEngine" title="Freeze">Freeze</a></li><li><a href="#impl-RefUnwindSafe-for-CurationEngine" title="RefUnwindSafe">RefUnwindSafe</a></li><li><a href="#impl-Send-for-CurationEngine" title="Send">Send</a></li><li><a href="#impl-Sync-for-CurationEngine" title="Sync">Sync</a></li><li><a href="#impl-Unpin-for-CurationEngine" title="Unpin">Unpin</a></li><li><a href="#impl-UnwindSafe-for-CurationEngine" title="UnwindSafe">UnwindSafe</a></li></ul><h3><a href="#blanket-implementations">Blanket Implementations</a></h3><ul class="block blanket-implementation"><li><a href="#impl-Any-for-T" title="Any">Any</a></li><li><a href="#impl-Borrow%3CT%3E-for-T" title="Borrow<T>">Borrow<T></a></li><li><a href="#impl-BorrowMut%3CT%3E-for-T" title="BorrowMut<T>">BorrowMut<T></a></li><li><a href="#impl-From%3CT%3E-for-T" title="From<T>">From<T></a></li><li><a href="#impl-Into%3CU%3E-for-T" title="Into<U>">Into<U></a></li><li><a href="#impl-TryFrom%3CU%3E-for-T" title="TryFrom<U>">TryFrom<U></a></li><li><a href="#impl-TryInto%3CU%3E-for-T" title="TryInto<U>">TryInto<U></a></li></ul></section><div id="rustdoc-modnav"><h2 class="in-crate"><a href="index.html">In crate chrs_<wbr>slurp</a></h2></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><div class="rustdoc-breadcrumbs"><a href="index.html">chrs_slurp</a></div><h1>Struct <span class="struct">CurationEngine</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/chrs_slurp/lib.rs.html#98-100">Source</a> </span></div><pre class="rust item-decl"><code>pub struct CurationEngine { <span class="comment">/* private fields */</span> }</code></pre><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Core engine that validates and persists <code>DecisionRecord</code>s into the
|
||||
Dolt‑backed graph.</p>
|
||||
<h2 id="why"><a class="doc-anchor" href="#why">§</a>Why</h2>
|
||||
<p>Centralising curation logic ensures a single place for validation and
|
||||
storage semantics, keeping the rest of the codebase agnostic of the graph
|
||||
implementation details.</p>
|
||||
</div></details><h2 id="implementations" class="section-header">Implementations<a href="#implementations" class="anchor">§</a></h2><div id="implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-CurationEngine" class="impl"><a class="src rightside" href="../src/chrs_slurp/lib.rs.html#102-156">Source</a><a href="#impl-CurationEngine" class="anchor">§</a><h3 class="code-header">impl <a class="struct" href="struct.CurationEngine.html" title="struct chrs_slurp::CurationEngine">CurationEngine</a></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.new" class="method"><a class="src rightside" href="../src/chrs_slurp/lib.rs.html#108-110">Source</a><h4 class="code-header">pub fn <a href="#method.new" class="fn">new</a>(graph: <a class="struct" href="../chrs_graph/struct.DoltGraph.html" title="struct chrs_graph::DoltGraph">DoltGraph</a>) -> Self</h4></section></summary><div class="docblock"><p>Creates a new <code>CurationEngine</code> bound to the supplied <code>DoltGraph</code>.</p>
|
||||
<p>The engine holds a reference to the graph for the lifetime of the
|
||||
instance; callers are responsible for providing a correctly initialised
|
||||
graph.</p>
|
||||
</div></details><details class="toggle method-toggle" open><summary><section id="method.curate_decision" class="method"><a class="src rightside" href="../src/chrs_slurp/lib.rs.html#127-155">Source</a><h4 class="code-header">pub fn <a href="#method.curate_decision" class="fn">curate_decision</a>(&self, dr: <a class="struct" href="struct.DecisionRecord.html" title="struct chrs_slurp::DecisionRecord">DecisionRecord</a>) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.unit.html">()</a>, <a class="enum" href="enum.SlurpError.html" title="enum chrs_slurp::SlurpError">SlurpError</a>></h4></section></summary><div class="docblock"><p>Validates the citations in <code>dr</code> and persists the decision into the
|
||||
graph.</p>
|
||||
<p>The method performs three steps:</p>
|
||||
<ol>
|
||||
<li><strong>Citation validation</strong> – each citation string is parsed into a
|
||||
<code>UCXLAddress</code>. Invalid citations produce a <code>ValidationError</code>.</li>
|
||||
<li><strong>Table assurance</strong> – attempts to create the <code>curated_decisions</code>
|
||||
table if it does not already exist. Errors are ignored because the
|
||||
table may already be present.</li>
|
||||
<li><strong>Insertion & commit</strong> – the decision is serialised to JSON and
|
||||
inserted as a node, then the graph transaction is committed.</li>
|
||||
</ol>
|
||||
<h5 id="errors"><a class="doc-anchor" href="#errors">§</a>Errors</h5>
|
||||
<p>Propagates any <code>GraphError</code>, <code>serde_json::Error</code>, or custom
|
||||
validation failures.</p>
|
||||
</div></details></div></details></div><h2 id="synthetic-implementations" class="section-header">Auto Trait Implementations<a href="#synthetic-implementations" class="anchor">§</a></h2><div id="synthetic-implementations-list"><section id="impl-Freeze-for-CurationEngine" class="impl"><a href="#impl-Freeze-for-CurationEngine" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Freeze.html" title="trait core::marker::Freeze">Freeze</a> for <a class="struct" href="struct.CurationEngine.html" title="struct chrs_slurp::CurationEngine">CurationEngine</a></h3></section><section id="impl-RefUnwindSafe-for-CurationEngine" class="impl"><a href="#impl-RefUnwindSafe-for-CurationEngine" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/panic/unwind_safe/trait.RefUnwindSafe.html" title="trait core::panic::unwind_safe::RefUnwindSafe">RefUnwindSafe</a> for <a class="struct" href="struct.CurationEngine.html" title="struct chrs_slurp::CurationEngine">CurationEngine</a></h3></section><section id="impl-Send-for-CurationEngine" class="impl"><a href="#impl-Send-for-CurationEngine" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Send.html" title="trait core::marker::Send">Send</a> for <a class="struct" href="struct.CurationEngine.html" title="struct chrs_slurp::CurationEngine">CurationEngine</a></h3></section><section id="impl-Sync-for-CurationEngine" class="impl"><a href="#impl-Sync-for-CurationEngine" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sync.html" title="trait core::marker::Sync">Sync</a> for <a class="struct" href="struct.CurationEngine.html" title="struct chrs_slurp::CurationEngine">CurationEngine</a></h3></section><section id="impl-Unpin-for-CurationEngine" class="impl"><a href="#impl-Unpin-for-CurationEngine" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Unpin.html" title="trait core::marker::Unpin">Unpin</a> for <a class="struct" href="struct.CurationEngine.html" title="struct chrs_slurp::CurationEngine">CurationEngine</a></h3></section><section id="impl-UnwindSafe-for-CurationEngine" class="impl"><a href="#impl-UnwindSafe-for-CurationEngine" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/panic/unwind_safe/trait.UnwindSafe.html" title="trait core::panic::unwind_safe::UnwindSafe">UnwindSafe</a> for <a class="struct" href="struct.CurationEngine.html" title="struct chrs_slurp::CurationEngine">CurationEngine</a></h3></section></div><h2 id="blanket-implementations" class="section-header">Blanket Implementations<a href="#blanket-implementations" class="anchor">§</a></h2><div id="blanket-implementations-list"><details class="toggle implementors-toggle"><summary><section id="impl-Any-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/any.rs.html#138">Source</a><a href="#impl-Any-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html" title="trait core::any::Any">Any</a> for T<div class="where">where
|
||||
T: 'static + ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.type_id" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/any.rs.html#139">Source</a><a href="#method.type_id" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html#tymethod.type_id" class="fn">type_id</a>(&self) -> <a class="struct" href="https://doc.rust-lang.org/1.87.0/core/any/struct.TypeId.html" title="struct core::any::TypeId">TypeId</a></h4></section></summary><div class='docblock'>Gets the <code>TypeId</code> of <code>self</code>. <a href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html#tymethod.type_id">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-Borrow%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#209">Source</a><a href="#impl-Borrow%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html" title="trait core::borrow::Borrow">Borrow</a><T> for T<div class="where">where
|
||||
T: ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#211">Source</a><a href="#method.borrow" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html#tymethod.borrow" class="fn">borrow</a>(&self) -> <a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.reference.html">&T</a></h4></section></summary><div class='docblock'>Immutably borrows from an owned value. <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html#tymethod.borrow">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-BorrowMut%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#217">Source</a><a href="#impl-BorrowMut%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html" title="trait core::borrow::BorrowMut">BorrowMut</a><T> for T<div class="where">where
|
||||
T: ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow_mut" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#218">Source</a><a href="#method.borrow_mut" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html#tymethod.borrow_mut" class="fn">borrow_mut</a>(&mut self) -> <a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.reference.html">&mut T</a></h4></section></summary><div class='docblock'>Mutably borrows from an owned value. <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html#tymethod.borrow_mut">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-From%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#767">Source</a><a href="#impl-From%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T> for T</h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.from" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#770">Source</a><a href="#method.from" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html#tymethod.from" class="fn">from</a>(t: T) -> T</h4></section></summary><div class="docblock"><p>Returns the argument unchanged.</p>
|
||||
</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-Into%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#750-752">Source</a><a href="#impl-Into%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html" title="trait core::convert::Into">Into</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.into" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#760">Source</a><a href="#method.into" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html#tymethod.into" class="fn">into</a>(self) -> U</h4></section></summary><div class="docblock"><p>Calls <code>U::from(self)</code>.</p>
|
||||
<p>That is, this conversion is whatever the implementation of
|
||||
<code><a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T> for U</code> chooses to do.</p>
|
||||
</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-TryFrom%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#806-808">Source</a><a href="#impl-TryFrom%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html" title="trait core::convert::Into">Into</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle" open><summary><section id="associatedtype.Error-1" class="associatedtype trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#810">Source</a><a href="#associatedtype.Error-1" class="anchor">§</a><h4 class="code-header">type <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" class="associatedtype">Error</a> = <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/convert/enum.Infallible.html" title="enum core::convert::Infallible">Infallible</a></h4></section></summary><div class='docblock'>The type returned in the event of a conversion error.</div></details><details class="toggle method-toggle" open><summary><section id="method.try_from" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#813">Source</a><a href="#method.try_from" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#tymethod.try_from" class="fn">try_from</a>(value: U) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><T, <T as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><U>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a>></h4></section></summary><div class='docblock'>Performs the conversion.</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-TryInto%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#791-793">Source</a><a href="#impl-TryInto%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html" title="trait core::convert::TryInto">TryInto</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle" open><summary><section id="associatedtype.Error" class="associatedtype trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#795">Source</a><a href="#associatedtype.Error" class="anchor">§</a><h4 class="code-header">type <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html#associatedtype.Error" class="associatedtype">Error</a> = <U as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a></h4></section></summary><div class='docblock'>The type returned in the event of a conversion error.</div></details><details class="toggle method-toggle" open><summary><section id="method.try_into" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#798">Source</a><a href="#method.try_into" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html#tymethod.try_into" class="fn">try_into</a>(self) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><U, <U as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a>></h4></section></summary><div class='docblock'>Performs the conversion.</div></details></div></details></div></section></div></main></body></html>
|
||||
38
target/doc/chrs_slurp/struct.DecisionRecord.html
Normal file
38
target/doc/chrs_slurp/struct.DecisionRecord.html
Normal file
File diff suppressed because one or more lines are too long
1
target/doc/chrs_sync/all.html
Normal file
1
target/doc/chrs_sync/all.html
Normal file
@@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="List of all items in this crate"><title>List of all items in this crate</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_sync" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod sys"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_sync/index.html">chrs_<wbr>sync</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h3><a href="#structs">Crate Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><h1>List of all items</h1><h3 id="structs">Structs</h3><ul class="all-items"><li><a href="struct.SyncManager.html">SyncManager</a></li></ul></section></div></main></body></html>
|
||||
1
target/doc/chrs_sync/index.html
Normal file
1
target/doc/chrs_sync/index.html
Normal file
@@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="API documentation for the Rust `chrs_sync` crate."><title>chrs_sync - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_sync" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="../crates.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod crate"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_sync/index.html">chrs_<wbr>sync</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><ul class="block"><li><a id="all-types" href="all.html">All Items</a></li></ul><section id="rustdoc-toc"><h3><a href="#structs">Crate Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1>Crate <span>chrs_sync</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/chrs_sync/lib.rs.html#1-116">Source</a> </span></div><h2 id="structs" class="section-header">Structs<a href="#structs" class="anchor">§</a></h2><dl class="item-table"><dt><a class="struct" href="struct.SyncManager.html" title="struct chrs_sync::SyncManager">Sync<wbr>Manager</a></dt><dd>Manages synchronization of a Dolt repository across peers.</dd></dl></section></div></main></body></html>
|
||||
1
target/doc/chrs_sync/sidebar-items.js
Normal file
1
target/doc/chrs_sync/sidebar-items.js
Normal file
@@ -0,0 +1 @@
|
||||
window.SIDEBAR_ITEMS = {"struct":["SyncManager"]};
|
||||
52
target/doc/chrs_sync/struct.SyncManager.html
Normal file
52
target/doc/chrs_sync/struct.SyncManager.html
Normal file
@@ -0,0 +1,52 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Manages synchronization of a Dolt repository across peers."><title>SyncManager in chrs_sync - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="chrs_sync" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../static.files/storage-82c7156e.js"></script><script defer src="sidebar-items.js"></script><script defer src="../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc struct"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../chrs_sync/index.html">chrs_<wbr>sync</a><span class="version">0.1.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">Sync<wbr>Manager</a></h2><h3><a href="#">Sections</a></h3><ul class="block top-toc"><li><a href="#fields-1" title="Fields">Fields</a></li><li><a href="#rationale" title="Rationale">Rationale</a></li></ul><h3><a href="#implementations">Methods</a></h3><ul class="block method"><li><a href="#method.broadcast_state" title="broadcast_state">broadcast_state</a></li><li><a href="#method.handle_sync_signal" title="handle_sync_signal">handle_sync_signal</a></li><li><a href="#method.new" title="new">new</a></li></ul><h3><a href="#synthetic-implementations">Auto Trait Implementations</a></h3><ul class="block synthetic-implementation"><li><a href="#impl-Freeze-for-SyncManager" title="!Freeze">!Freeze</a></li><li><a href="#impl-RefUnwindSafe-for-SyncManager" title="!RefUnwindSafe">!RefUnwindSafe</a></li><li><a href="#impl-Sync-for-SyncManager" title="!Sync">!Sync</a></li><li><a href="#impl-UnwindSafe-for-SyncManager" title="!UnwindSafe">!UnwindSafe</a></li><li><a href="#impl-Send-for-SyncManager" title="Send">Send</a></li><li><a href="#impl-Unpin-for-SyncManager" title="Unpin">Unpin</a></li></ul><h3><a href="#blanket-implementations">Blanket Implementations</a></h3><ul class="block blanket-implementation"><li><a href="#impl-Any-for-T" title="Any">Any</a></li><li><a href="#impl-Borrow%3CT%3E-for-T" title="Borrow<T>">Borrow<T></a></li><li><a href="#impl-BorrowMut%3CT%3E-for-T" title="BorrowMut<T>">BorrowMut<T></a></li><li><a href="#impl-From%3CT%3E-for-T" title="From<T>">From<T></a></li><li><a href="#impl-Into%3CU%3E-for-T" title="Into<U>">Into<U></a></li><li><a href="#impl-TryFrom%3CU%3E-for-T" title="TryFrom<U>">TryFrom<U></a></li><li><a href="#impl-TryInto%3CU%3E-for-T" title="TryInto<U>">TryInto<U></a></li></ul></section><div id="rustdoc-modnav"><h2 class="in-crate"><a href="index.html">In crate chrs_<wbr>sync</a></h2></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><div class="rustdoc-breadcrumbs"><a href="index.html">chrs_sync</a></div><h1>Struct <span class="struct">SyncManager</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/chrs_sync/lib.rs.html#24-27">Source</a> </span></div><pre class="rust item-decl"><code>pub struct SyncManager { <span class="comment">/* private fields */</span> }</code></pre><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Manages synchronization of a Dolt repository across peers.</p>
|
||||
<h2 id="fields-1"><a class="doc-anchor" href="#fields-1">§</a>Fields</h2>
|
||||
<ul>
|
||||
<li><code>mailbox</code> – The <code>Mailbox</code> instance used to send and receive messages.</li>
|
||||
<li><code>repo_path</code> – Filesystem path to the local Dolt repository.</li>
|
||||
</ul>
|
||||
<h2 id="rationale"><a class="doc-anchor" href="#rationale">§</a>Rationale</h2>
|
||||
<p>The CHORUS architecture relies on deterministic state replication. By
|
||||
broadcasting the latest commit hash (<code>sync_signal</code>) each peer can decide
|
||||
whether to pull updates. This struct encapsulates that behaviour, keeping the
|
||||
rest of the system agnostic of the underlying VCS commands.</p>
|
||||
</div></details><h2 id="implementations" class="section-header">Implementations<a href="#implementations" class="anchor">§</a></h2><div id="implementations-list"><details class="toggle implementors-toggle" open><summary><section id="impl-SyncManager" class="impl"><a class="src rightside" href="../src/chrs_sync/lib.rs.html#29-116">Source</a><a href="#impl-SyncManager" class="anchor">§</a><h3 class="code-header">impl <a class="struct" href="struct.SyncManager.html" title="struct chrs_sync::SyncManager">SyncManager</a></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.new" class="method"><a class="src rightside" href="../src/chrs_sync/lib.rs.html#38-40">Source</a><h4 class="code-header">pub fn <a href="#method.new" class="fn">new</a>(mailbox: <a class="struct" href="../chrs_mail/struct.Mailbox.html" title="struct chrs_mail::Mailbox">Mailbox</a>, repo_path: <a class="struct" href="https://doc.rust-lang.org/1.87.0/std/path/struct.PathBuf.html" title="struct std::path::PathBuf">PathBuf</a>) -> Self</h4></section></summary><div class="docblock"><p>Creates a new <code>SyncManager</code>.</p>
|
||||
<h5 id="parameters"><a class="doc-anchor" href="#parameters">§</a>Parameters</h5>
|
||||
<ul>
|
||||
<li><code>mailbox</code> – An already‑opened <code>Mailbox</code> for peer communication.</li>
|
||||
<li><code>repo_path</code> – Path to the Dolt repository that should be kept in sync.</li>
|
||||
</ul>
|
||||
<p>Returns a fully‑initialised manager ready to broadcast or handle sync
|
||||
signals.</p>
|
||||
</div></details><details class="toggle method-toggle" open><summary><section id="method.broadcast_state" class="method"><a class="src rightside" href="../src/chrs_sync/lib.rs.html#54-83">Source</a><h4 class="code-header">pub fn <a href="#method.broadcast_state" class="fn">broadcast_state</a>(
|
||||
&self,
|
||||
from_peer: &<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.str.html">str</a>,
|
||||
to_peer: &<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.str.html">str</a>,
|
||||
) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.unit.html">()</a>, <a class="struct" href="https://doc.rust-lang.org/1.87.0/alloc/boxed/struct.Box.html" title="struct alloc::boxed::Box">Box</a><dyn <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/error/trait.Error.html" title="trait core::error::Error">Error</a>>></h4></section></summary><div class="docblock"><p>Broadcasts the current repository state to a remote peer.</p>
|
||||
<p>The method executes <code>dolt log -n 1 --format %H</code> to obtain the most recent
|
||||
commit hash, constructs a <code>Message</code> with topic <code>"sync_signal"</code> and sends it
|
||||
via the mailbox.</p>
|
||||
<ul>
|
||||
<li><code>from_peer</code> – Identifier of the sender.</li>
|
||||
<li><code>to_peer</code> – Identifier of the intended recipient.</li>
|
||||
</ul>
|
||||
<h5 id="errors"><a class="doc-anchor" href="#errors">§</a>Errors</h5>
|
||||
<p>Returns any I/O or command‑execution error wrapped in a boxed <code>dyn Error</code>.</p>
|
||||
</div></details><details class="toggle method-toggle" open><summary><section id="method.handle_sync_signal" class="method"><a class="src rightside" href="../src/chrs_sync/lib.rs.html#95-115">Source</a><h4 class="code-header">pub fn <a href="#method.handle_sync_signal" class="fn">handle_sync_signal</a>(&self, msg: &<a class="struct" href="../chrs_mail/struct.Message.html" title="struct chrs_mail::Message">Message</a>) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.unit.html">()</a>, <a class="struct" href="https://doc.rust-lang.org/1.87.0/alloc/boxed/struct.Box.html" title="struct alloc::boxed::Box">Box</a><dyn <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/error/trait.Error.html" title="trait core::error::Error">Error</a>>></h4></section></summary><div class="docblock"><p>Handles an incoming <code>sync_signal</code> message.</p>
|
||||
<p>If the message topic is not <code>"sync_signal"</code> the function returns <code>Ok(())</code>
|
||||
immediately. Otherwise it extracts the remote commit hash and attempts a
|
||||
<code>dolt pull origin</code> to bring the local repository up‑to‑date. In a real
|
||||
P2P deployment the remote URL would be derived from the sender, but the
|
||||
current implementation uses the default remote configuration.</p>
|
||||
<h5 id="errors-1"><a class="doc-anchor" href="#errors-1">§</a>Errors</h5>
|
||||
<p>Propagates any command execution failures.</p>
|
||||
</div></details></div></details></div><h2 id="synthetic-implementations" class="section-header">Auto Trait Implementations<a href="#synthetic-implementations" class="anchor">§</a></h2><div id="synthetic-implementations-list"><section id="impl-Freeze-for-SyncManager" class="impl"><a href="#impl-Freeze-for-SyncManager" class="anchor">§</a><h3 class="code-header">impl !<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Freeze.html" title="trait core::marker::Freeze">Freeze</a> for <a class="struct" href="struct.SyncManager.html" title="struct chrs_sync::SyncManager">SyncManager</a></h3></section><section id="impl-RefUnwindSafe-for-SyncManager" class="impl"><a href="#impl-RefUnwindSafe-for-SyncManager" class="anchor">§</a><h3 class="code-header">impl !<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/panic/unwind_safe/trait.RefUnwindSafe.html" title="trait core::panic::unwind_safe::RefUnwindSafe">RefUnwindSafe</a> for <a class="struct" href="struct.SyncManager.html" title="struct chrs_sync::SyncManager">SyncManager</a></h3></section><section id="impl-Send-for-SyncManager" class="impl"><a href="#impl-Send-for-SyncManager" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Send.html" title="trait core::marker::Send">Send</a> for <a class="struct" href="struct.SyncManager.html" title="struct chrs_sync::SyncManager">SyncManager</a></h3></section><section id="impl-Sync-for-SyncManager" class="impl"><a href="#impl-Sync-for-SyncManager" class="anchor">§</a><h3 class="code-header">impl !<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sync.html" title="trait core::marker::Sync">Sync</a> for <a class="struct" href="struct.SyncManager.html" title="struct chrs_sync::SyncManager">SyncManager</a></h3></section><section id="impl-Unpin-for-SyncManager" class="impl"><a href="#impl-Unpin-for-SyncManager" class="anchor">§</a><h3 class="code-header">impl <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Unpin.html" title="trait core::marker::Unpin">Unpin</a> for <a class="struct" href="struct.SyncManager.html" title="struct chrs_sync::SyncManager">SyncManager</a></h3></section><section id="impl-UnwindSafe-for-SyncManager" class="impl"><a href="#impl-UnwindSafe-for-SyncManager" class="anchor">§</a><h3 class="code-header">impl !<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/panic/unwind_safe/trait.UnwindSafe.html" title="trait core::panic::unwind_safe::UnwindSafe">UnwindSafe</a> for <a class="struct" href="struct.SyncManager.html" title="struct chrs_sync::SyncManager">SyncManager</a></h3></section></div><h2 id="blanket-implementations" class="section-header">Blanket Implementations<a href="#blanket-implementations" class="anchor">§</a></h2><div id="blanket-implementations-list"><details class="toggle implementors-toggle"><summary><section id="impl-Any-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/any.rs.html#138">Source</a><a href="#impl-Any-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html" title="trait core::any::Any">Any</a> for T<div class="where">where
|
||||
T: 'static + ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.type_id" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/any.rs.html#139">Source</a><a href="#method.type_id" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html#tymethod.type_id" class="fn">type_id</a>(&self) -> <a class="struct" href="https://doc.rust-lang.org/1.87.0/core/any/struct.TypeId.html" title="struct core::any::TypeId">TypeId</a></h4></section></summary><div class='docblock'>Gets the <code>TypeId</code> of <code>self</code>. <a href="https://doc.rust-lang.org/1.87.0/core/any/trait.Any.html#tymethod.type_id">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-Borrow%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#209">Source</a><a href="#impl-Borrow%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html" title="trait core::borrow::Borrow">Borrow</a><T> for T<div class="where">where
|
||||
T: ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#211">Source</a><a href="#method.borrow" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html#tymethod.borrow" class="fn">borrow</a>(&self) -> <a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.reference.html">&T</a></h4></section></summary><div class='docblock'>Immutably borrows from an owned value. <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.Borrow.html#tymethod.borrow">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-BorrowMut%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#217">Source</a><a href="#impl-BorrowMut%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html" title="trait core::borrow::BorrowMut">BorrowMut</a><T> for T<div class="where">where
|
||||
T: ?<a class="trait" href="https://doc.rust-lang.org/1.87.0/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.borrow_mut" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/borrow.rs.html#218">Source</a><a href="#method.borrow_mut" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html#tymethod.borrow_mut" class="fn">borrow_mut</a>(&mut self) -> <a class="primitive" href="https://doc.rust-lang.org/1.87.0/std/primitive.reference.html">&mut T</a></h4></section></summary><div class='docblock'>Mutably borrows from an owned value. <a href="https://doc.rust-lang.org/1.87.0/core/borrow/trait.BorrowMut.html#tymethod.borrow_mut">Read more</a></div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-From%3CT%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#767">Source</a><a href="#impl-From%3CT%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T> for T</h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.from" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#770">Source</a><a href="#method.from" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html#tymethod.from" class="fn">from</a>(t: T) -> T</h4></section></summary><div class="docblock"><p>Returns the argument unchanged.</p>
|
||||
</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-Into%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#750-752">Source</a><a href="#impl-Into%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html" title="trait core::convert::Into">Into</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle method-toggle" open><summary><section id="method.into" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#760">Source</a><a href="#method.into" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html#tymethod.into" class="fn">into</a>(self) -> U</h4></section></summary><div class="docblock"><p>Calls <code>U::from(self)</code>.</p>
|
||||
<p>That is, this conversion is whatever the implementation of
|
||||
<code><a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.From.html" title="trait core::convert::From">From</a><T> for U</code> chooses to do.</p>
|
||||
</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-TryFrom%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#806-808">Source</a><a href="#impl-TryFrom%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.Into.html" title="trait core::convert::Into">Into</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle" open><summary><section id="associatedtype.Error-1" class="associatedtype trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#810">Source</a><a href="#associatedtype.Error-1" class="anchor">§</a><h4 class="code-header">type <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" class="associatedtype">Error</a> = <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/convert/enum.Infallible.html" title="enum core::convert::Infallible">Infallible</a></h4></section></summary><div class='docblock'>The type returned in the event of a conversion error.</div></details><details class="toggle method-toggle" open><summary><section id="method.try_from" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#813">Source</a><a href="#method.try_from" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#tymethod.try_from" class="fn">try_from</a>(value: U) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><T, <T as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><U>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a>></h4></section></summary><div class='docblock'>Performs the conversion.</div></details></div></details><details class="toggle implementors-toggle"><summary><section id="impl-TryInto%3CU%3E-for-T" class="impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#791-793">Source</a><a href="#impl-TryInto%3CU%3E-for-T" class="anchor">§</a><h3 class="code-header">impl<T, U> <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html" title="trait core::convert::TryInto">TryInto</a><U> for T<div class="where">where
|
||||
U: <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>,</div></h3></section></summary><div class="impl-items"><details class="toggle" open><summary><section id="associatedtype.Error" class="associatedtype trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#795">Source</a><a href="#associatedtype.Error" class="anchor">§</a><h4 class="code-header">type <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html#associatedtype.Error" class="associatedtype">Error</a> = <U as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a></h4></section></summary><div class='docblock'>The type returned in the event of a conversion error.</div></details><details class="toggle method-toggle" open><summary><section id="method.try_into" class="method trait-impl"><a class="src rightside" href="https://doc.rust-lang.org/1.87.0/src/core/convert/mod.rs.html#798">Source</a><a href="#method.try_into" class="anchor">§</a><h4 class="code-header">fn <a href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryInto.html#tymethod.try_into" class="fn">try_into</a>(self) -> <a class="enum" href="https://doc.rust-lang.org/1.87.0/core/result/enum.Result.html" title="enum core::result::Result">Result</a><U, <U as <a class="trait" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html" title="trait core::convert::TryFrom">TryFrom</a><T>>::<a class="associatedtype" href="https://doc.rust-lang.org/1.87.0/core/convert/trait.TryFrom.html#associatedtype.Error" title="type core::convert::TryFrom::Error">Error</a>></h4></section></summary><div class='docblock'>Performs the conversion.</div></details></div></details></div></section></div></main></body></html>
|
||||
2
target/doc/crates.js
Normal file
2
target/doc/crates.js
Normal file
@@ -0,0 +1,2 @@
|
||||
window.ALL_CRATES = ["chrs_agent","chrs_bubble","chrs_graph","chrs_mail","chrs_poc","chrs_shhh","chrs_slurp","chrs_sync","ucxl"];
|
||||
//{"start":21,"fragment_lengths":[12,14,13,12,11,12,13,12,7]}
|
||||
1
target/doc/help.html
Normal file
1
target/doc/help.html
Normal file
@@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Documentation for Rustdoc"><title>Help</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="./static.files/${f}">`).join(""))</script><link rel="stylesheet" href="./static.files/normalize-9960930a.css"><link rel="stylesheet" href="./static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="./" data-static-root-path="./static.files/" data-current-crate="chrs_poc" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="./static.files/storage-82c7156e.js"></script><script defer src="./static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="./static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="./static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="./static.files/favicon-044be391.svg"></head><body class="rustdoc mod sys"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button><a class="logo-container" href="./index.html"><img class="rust-logo" src="./static.files/rust-logo-9a9549ea.svg" alt=""></a></nav><nav class="sidebar"><div class="sidebar-crate"><a class="logo-container" href="./index.html"><img class="rust-logo" src="./static.files/rust-logo-9a9549ea.svg" alt="logo"></a><h2><a href="./index.html">Rustdoc</a><span class="version">1.87.0</span></h2></div><div class="version">(17067e9ac 2025-05-09)</div><h2 class="location">Help</h2><div class="sidebar-elems"></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1>Rustdoc help</h1><span class="out-of-band"><a id="back" href="javascript:void(0)" onclick="history.back();">Back</a></span></div><noscript><section><p>You need to enable JavaScript to use keyboard commands or search.</p><p>For more information, browse the <a href="https://doc.rust-lang.org/1.87.0/rustdoc/">rustdoc handbook</a>.</p></section></noscript></section></div></main></body></html>
|
||||
4
target/doc/search-index.js
Normal file
4
target/doc/search-index.js
Normal file
File diff suppressed because one or more lines are too long
1
target/doc/search.desc/chrs_agent/chrs_agent-desc-0-.js
Normal file
1
target/doc/search.desc/chrs_agent/chrs_agent-desc-0-.js
Normal file
@@ -0,0 +1 @@
|
||||
searchState.loadedDescShard("chrs_agent", 0, "Represents a running CHORUS agent.\nReturns the argument unchanged.\nInitializes a new <code>CHORUSAgent</code>.\nCalls <code>U::from(self)</code>.\nEntry point for the CHORUS agent binary.\nMain event loop of the agent.")
|
||||
@@ -0,0 +1 @@
|
||||
searchState.loadedDescShard("chrs_bubble", 0, "Errors that can arise when working with a <code>ProvenanceGraph</code>.\nThe target node <em>cites</em> the source node.\nThe target node was <em>derived</em> from the source node.\nThe target node was <em>influenced</em> by the source node.\nRepresents the kind of relationship between two provenance …\nCore structure that maintains an in‑memory DAG of …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls <code>U::from(self)</code>.\nCalls <code>U::from(self)</code>.\nCalls <code>U::from(self)</code>.\nCreates a new <code>ProvenanceGraph</code> backed by a …\nRecords a directed edge between two existing nodes.\nRecords a provenance node with a unique <code>Uuid</code> and an …")
|
||||
1
target/doc/search.desc/chrs_graph/chrs_graph-desc-0-.js
Normal file
1
target/doc/search.desc/chrs_graph/chrs_graph-desc-0-.js
Normal file
@@ -0,0 +1 @@
|
||||
searchState.loadedDescShard("chrs_graph", 0, "chrs-graph library implementation using Dolt for graph …\nRepresents a failure when executing a Dolt command.\nWrapper around a Dolt repository that stores graph data.\nEnumeration of possible errors that can arise while …\nPropagates I/O errors from the standard library (e.g., …\nA generic catch‑all for errors that don’t fit the …\nPropagates JSON (de)serialization errors from <code>serde_json</code>.\nStage all changes and commit them with the provided <code>message</code>…\nCreate a SQL table within the Dolt repository.\nReturns the argument unchanged.\nReturns the argument unchanged.\nInitialise (or open) a Dolt repository at the given <code>path</code>.\nInsert a node represented by a JSON object into the …\nCalls <code>U::from(self)</code>.\nCalls <code>U::from(self)</code>.\nFilesystem path to the root of the Dolt repository.")
|
||||
1
target/doc/search.desc/chrs_mail/chrs_mail-desc-0-.js
Normal file
1
target/doc/search.desc/chrs_mail/chrs_mail-desc-0-.js
Normal file
@@ -0,0 +1 @@
|
||||
searchState.loadedDescShard("chrs_mail", 0, "chrs-mail library implementation\nPropagates chrono parsing errors, primarily when …\nPropagates JSON (de)serialization errors from <code>serde_json</code>.\nErrors that can occur while using the <code>Mailbox</code>.\nWrapper around a SQLite connection providing …\nRepresents a mail message stored in the mailbox.\nPropagates any <code>rusqlite::Error</code> encountered while …\nPropagates UUID parsing errors.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nIdentifier of the sending peer.\nGlobally unique identifier for the message.\nCalls <code>U::from(self)</code>.\nCalls <code>U::from(self)</code>.\nCalls <code>U::from(self)</code>.\nMark a message as read by setting its <code>read_at</code> timestamp.\nOpen (or create) a mailbox database at <code>path</code>.\nArbitrary JSON payload containing the message body.\nOptional timestamp (UTC) when the recipient read the …\nRetrieve all unread messages addressed to <code>peer_id</code>.\nStore a new message in the mailbox.\nTimestamp (UTC) when the message was sent.\nIdentifier of the receiving peer.\nTopic or channel of the message; used for routing/filters.")
|
||||
1
target/doc/search.desc/chrs_poc/chrs_poc-desc-0-.js
Normal file
1
target/doc/search.desc/chrs_poc/chrs_poc-desc-0-.js
Normal file
@@ -0,0 +1 @@
|
||||
searchState.loadedDescShard("chrs_poc", 0, "Entry point for the proof‑of‑concept binary.")
|
||||
1
target/doc/search.desc/chrs_shhh/chrs_shhh-desc-0-.js
Normal file
1
target/doc/search.desc/chrs_shhh/chrs_shhh-desc-0-.js
Normal file
@@ -0,0 +1 @@
|
||||
searchState.loadedDescShard("chrs_shhh", 0, "Represents a single rule used to redact a secret.\nThe main entry point for secret detection and redaction.\nChecks whether any of the configured rules match <code>input</code>.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls <code>U::from(self)</code>.\nCalls <code>U::from(self)</code>.\nHuman‑readable name for the rule.\nConstructs a <code>SecretSentinel</code> pre‑populated with a …\nCompiled regular expression that matches the secret.\nText that will replace the matched secret.\nRedacts all secrets found in <code>input</code> according to the …")
|
||||
1
target/doc/search.desc/chrs_slurp/chrs_slurp-desc-0-.js
Normal file
1
target/doc/search.desc/chrs_slurp/chrs_slurp-desc-0-.js
Normal file
@@ -0,0 +1 @@
|
||||
searchState.loadedDescShard("chrs_slurp", 0, "chrs-slurp\nCore engine that validates and persists <code>DecisionRecord</code>s …\nA record representing a curated decision within the CHORUS …\nErrors that can arise while slurping (curating) a decision …\nIdentifier of the agent or human that authored the …\nSerialized UCXL addresses that serve as citations for the …\nValidates the citations in <code>dr</code> and persists the decision …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nUnique identifier for the decision.\nCalls <code>U::from(self)</code>.\nCalls <code>U::from(self)</code>.\nCalls <code>U::from(self)</code>.\nCreates a new <code>CurationEngine</code> bound to the supplied …\nFree‑form textual reasoning explaining the decision.\nThe moment the decision was created.")
|
||||
1
target/doc/search.desc/chrs_sync/chrs_sync-desc-0-.js
Normal file
1
target/doc/search.desc/chrs_sync/chrs_sync-desc-0-.js
Normal file
@@ -0,0 +1 @@
|
||||
searchState.loadedDescShard("chrs_sync", 0, "Manages synchronization of a Dolt repository across peers.\nBroadcasts the current repository state to a remote peer.\nReturns the argument unchanged.\nHandles an incoming <code>sync_signal</code> message.\nCalls <code>U::from(self)</code>.\nCreates a new <code>SyncManager</code>.")
|
||||
1
target/doc/search.desc/ucxl/ucxl-desc-0-.js
Normal file
1
target/doc/search.desc/ucxl/ucxl-desc-0-.js
Normal file
@@ -0,0 +1 @@
|
||||
searchState.loadedDescShard("ucxl", 0, "UCXL core data structures and utilities.\nFuture (“^^”) – a speculative or planned version of …\nIn‑memory implementation of <code>MetadataStore</code> backed by a …\nTrait defining a simple key‑value metadata store.\nPast (“~~”) – a historical snapshot of a resource.\nPresent (“#”) – the current version of a resource.\nRepresents the temporal axis in a UCXL address.\nRepresents a parsed UCXL address.\nThe identifier of the agent (e.g., a user or system …\nFormats the temporal axis back to its string token.\nSerialises the address back to its canonical string form.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nParses a temporal axis token from its textual …\nParses a full UCXL address string into a <code>UCXLAddress</code> value.\nRetrieves the metadata for <code>path</code> if it exists.\nCalls <code>U::from(self)</code>.\nCalls <code>U::from(self)</code>.\nCalls <code>U::from(self)</code>.\nCreates a fresh, empty <code>InMemoryMetadataStore</code>.\nPath to the resource relative to the project root.\nThe project namespace this address belongs to.\nRemoves the metadata entry for <code>path</code>, returning the old …\nOptional role associated with the agent (e.g., “admin”…\nStores <code>metadata</code> for <code>path</code>, overwriting any existing value.\nThe specific task within the project.\nTemporal axis indicating present, past or future.\nUCXL filesystem watcher.\nRepresents a watcher rooted at a specific base path.\nReturns the argument unchanged.\nCalls <code>U::from(self)</code>.\nCreates a new <code>UCXLWatcher</code> for the given path.\nStarts the watch loop, blocking indefinitely while …")
|
||||
1
target/doc/settings.html
Normal file
1
target/doc/settings.html
Normal file
@@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Settings of Rustdoc"><title>Settings</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="./static.files/${f}">`).join(""))</script><link rel="stylesheet" href="./static.files/normalize-9960930a.css"><link rel="stylesheet" href="./static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="./" data-static-root-path="./static.files/" data-current-crate="chrs_poc" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="./static.files/storage-82c7156e.js"></script><script defer src="./static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="./static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="./static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="./static.files/favicon-044be391.svg"></head><body class="rustdoc mod sys"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button><a class="logo-container" href="./index.html"><img class="rust-logo" src="./static.files/rust-logo-9a9549ea.svg" alt=""></a></nav><nav class="sidebar"><div class="sidebar-crate"><a class="logo-container" href="./index.html"><img class="rust-logo" src="./static.files/rust-logo-9a9549ea.svg" alt="logo"></a><h2><a href="./index.html">Rustdoc</a><span class="version">1.87.0</span></h2></div><div class="version">(17067e9ac 2025-05-09)</div><h2 class="location">Settings</h2><div class="sidebar-elems"></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1>Rustdoc settings</h1><span class="out-of-band"><a id="back" href="javascript:void(0)" onclick="history.back();">Back</a></span></div><noscript><section>You need to enable JavaScript be able to update your settings.</section></noscript><script defer src="./static.files/settings-d72f25bb.js"></script></section></div></main></body></html>
|
||||
3
target/doc/src-files.js
Normal file
3
target/doc/src-files.js
Normal file
@@ -0,0 +1,3 @@
|
||||
var srcIndex = new Map(JSON.parse('[["chrs_agent",["",[],["main.rs"]]],["chrs_bubble",["",[],["lib.rs"]]],["chrs_graph",["",[],["lib.rs"]]],["chrs_mail",["",[],["lib.rs"]]],["chrs_poc",["",[],["main.rs"]]],["chrs_shhh",["",[],["lib.rs"]]],["chrs_slurp",["",[],["lib.rs"]]],["chrs_sync",["",[],["lib.rs"]]],["ucxl",["",[],["lib.rs","watcher.rs"]]]]'));
|
||||
createSrcSidebar();
|
||||
//{"start":36,"fragment_lengths":[34,35,34,33,33,33,34,33,41]}
|
||||
115
target/doc/src/chrs_agent/main.rs.html
Normal file
115
target/doc/src/chrs_agent/main.rs.html
Normal file
@@ -0,0 +1,115 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `chrs-agent/src/main.rs`."><title>main.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="chrs_agent" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../../static.files/storage-82c7156e.js"></script><script defer src="../../static.files/src-script-63605ae7.js"></script><script defer src="../../src-files.js"></script><script defer src="../../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer"></div><main><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1><div class="sub-heading">chrs_agent/</div>main.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="doccomment">/// chrs-agent crate implements the core CHORUS agent runtime.
|
||||
<a href=#2 id=2 data-nosnippet>2</a>///
|
||||
<a href=#3 id=3 data-nosnippet>3</a>/// An agent runs a message loop that receives tasks from a `Mailbox`, logs them to a
|
||||
<a href=#4 id=4 data-nosnippet>4</a>/// `DoltGraph` (the persistent state graph), and marks them as read. The design
|
||||
<a href=#5 id=5 data-nosnippet>5</a>/// follows the CHORUS architectural pattern where agents are autonomous workers
|
||||
<a href=#6 id=6 data-nosnippet>6</a>/// that interact through the `chrs_mail` messaging layer and maintain a provable
|
||||
<a href=#7 id=7 data-nosnippet>7</a>/// execution history in the graph.
|
||||
<a href=#8 id=8 data-nosnippet>8</a>
|
||||
<a href=#9 id=9 data-nosnippet>9</a></span><span class="kw">use </span>chrs_graph::DoltGraph;
|
||||
<a href=#10 id=10 data-nosnippet>10</a><span class="kw">use </span>chrs_mail::{Mailbox, Message};
|
||||
<a href=#11 id=11 data-nosnippet>11</a><span class="kw">use </span>chrono::Utc;
|
||||
<a href=#12 id=12 data-nosnippet>12</a><span class="kw">use </span>std::path::Path;
|
||||
<a href=#13 id=13 data-nosnippet>13</a><span class="kw">use </span>std::time::Duration;
|
||||
<a href=#14 id=14 data-nosnippet>14</a><span class="kw">use </span>tokio::time::sleep;
|
||||
<a href=#15 id=15 data-nosnippet>15</a><span class="kw">use </span>uuid::Uuid;
|
||||
<a href=#16 id=16 data-nosnippet>16</a>
|
||||
<a href=#17 id=17 data-nosnippet>17</a><span class="doccomment">/// Represents a running CHORUS agent.
|
||||
<a href=#18 id=18 data-nosnippet>18</a>///
|
||||
<a href=#19 id=19 data-nosnippet>19</a>/// # Fields
|
||||
<a href=#20 id=20 data-nosnippet>20</a>/// * `id` – Logical identifier for the agent (e.g., "agent-001").
|
||||
<a href=#21 id=21 data-nosnippet>21</a>/// * `mailbox` – The `Mailbox` used for inter‑agent communication.
|
||||
<a href=#22 id=22 data-nosnippet>22</a>/// * `graph` – Persistence layer (`DoltGraph`) where task logs are stored.
|
||||
<a href=#23 id=23 data-nosnippet>23</a>///
|
||||
<a href=#24 id=24 data-nosnippet>24</a>/// # Rationale
|
||||
<a href=#25 id=25 data-nosnippet>25</a>/// Agents are isolated units of work. By keeping a dedicated mailbox and a graph
|
||||
<a href=#26 id=26 data-nosnippet>26</a>/// per agent we guarantee that each agent can be started, stopped, and reasoned
|
||||
<a href=#27 id=27 data-nosnippet>27</a>/// about independently while still contributing to the global CHORUS state.
|
||||
<a href=#28 id=28 data-nosnippet>28</a></span><span class="kw">pub struct </span>CHORUSAgent {
|
||||
<a href=#29 id=29 data-nosnippet>29</a> id: String,
|
||||
<a href=#30 id=30 data-nosnippet>30</a> mailbox: Mailbox,
|
||||
<a href=#31 id=31 data-nosnippet>31</a> graph: DoltGraph,
|
||||
<a href=#32 id=32 data-nosnippet>32</a>}
|
||||
<a href=#33 id=33 data-nosnippet>33</a>
|
||||
<a href=#34 id=34 data-nosnippet>34</a><span class="kw">impl </span>CHORUSAgent {
|
||||
<a href=#35 id=35 data-nosnippet>35</a> <span class="doccomment">/// Initializes a new `CHORUSAgent`.
|
||||
<a href=#36 id=36 data-nosnippet>36</a> ///
|
||||
<a href=#37 id=37 data-nosnippet>37</a> /// This creates the filesystem layout under `base_path`, opens or creates the
|
||||
<a href=#38 id=38 data-nosnippet>38</a> /// SQLite mailbox, and initialises a `DoltGraph` for state persistence.
|
||||
<a href=#39 id=39 data-nosnippet>39</a> /// It also ensures that a `task_log` table exists for recording incoming
|
||||
<a href=#40 id=40 data-nosnippet>40</a> /// messages.
|
||||
<a href=#41 id=41 data-nosnippet>41</a> ///
|
||||
<a href=#42 id=42 data-nosnippet>42</a> /// # Parameters
|
||||
<a href=#43 id=43 data-nosnippet>43</a> /// * `id` – Identifier for the agent instance.
|
||||
<a href=#44 id=44 data-nosnippet>44</a> /// * `base_path` – Directory where the agent stores its data.
|
||||
<a href=#45 id=45 data-nosnippet>45</a> ///
|
||||
<a href=#46 id=46 data-nosnippet>46</a> /// Returns an instance ready to run its event loop.
|
||||
<a href=#47 id=47 data-nosnippet>47</a> </span><span class="kw">async fn </span>init(id: <span class="kw-2">&</span>str, base_path: <span class="kw-2">&</span>Path) -> <span class="prelude-ty">Result</span><<span class="self">Self</span>, Box<<span class="kw">dyn </span>std::error::Error>> {
|
||||
<a href=#48 id=48 data-nosnippet>48</a> <span class="kw">let </span>mail_path = base_path.join(<span class="string">"mail.sqlite"</span>);
|
||||
<a href=#49 id=49 data-nosnippet>49</a> <span class="kw">let </span>graph_path = base_path.join(<span class="string">"state_graph"</span>);
|
||||
<a href=#50 id=50 data-nosnippet>50</a>
|
||||
<a href=#51 id=51 data-nosnippet>51</a> std::fs::create_dir_all(<span class="kw-2">&</span>graph_path)<span class="question-mark">?</span>;
|
||||
<a href=#52 id=52 data-nosnippet>52</a>
|
||||
<a href=#53 id=53 data-nosnippet>53</a> <span class="kw">let </span>mailbox = Mailbox::open(mail_path)<span class="question-mark">?</span>;
|
||||
<a href=#54 id=54 data-nosnippet>54</a> <span class="kw">let </span>graph = DoltGraph::init(<span class="kw-2">&</span>graph_path)<span class="question-mark">?</span>;
|
||||
<a href=#55 id=55 data-nosnippet>55</a>
|
||||
<a href=#56 id=56 data-nosnippet>56</a> <span class="comment">// Ensure table exists
|
||||
<a href=#57 id=57 data-nosnippet>57</a> </span><span class="kw">let _ </span>= graph.create_table(<span class="string">"task_log"</span>, <span class="string">"id TEXT PRIMARY KEY, topic TEXT, payload TEXT, received_at TEXT"</span>);
|
||||
<a href=#58 id=58 data-nosnippet>58</a>
|
||||
<a href=#59 id=59 data-nosnippet>59</a> <span class="prelude-val">Ok</span>(<span class="self">Self </span>{
|
||||
<a href=#60 id=60 data-nosnippet>60</a> id: id.to_string(),
|
||||
<a href=#61 id=61 data-nosnippet>61</a> mailbox,
|
||||
<a href=#62 id=62 data-nosnippet>62</a> graph,
|
||||
<a href=#63 id=63 data-nosnippet>63</a> })
|
||||
<a href=#64 id=64 data-nosnippet>64</a> }
|
||||
<a href=#65 id=65 data-nosnippet>65</a>
|
||||
<a href=#66 id=66 data-nosnippet>66</a> <span class="doccomment">/// Main event loop of the agent.
|
||||
<a href=#67 id=67 data-nosnippet>67</a> ///
|
||||
<a href=#68 id=68 data-nosnippet>68</a> /// It repeatedly polls the mailbox for pending messages addressed to this
|
||||
<a href=#69 id=69 data-nosnippet>69</a> /// agent, logs each message into the `task_log` table, commits the graph, and
|
||||
<a href=#70 id=70 data-nosnippet>70</a> /// acknowledges the message. The loop sleeps for a configurable interval to
|
||||
<a href=#71 id=71 data-nosnippet>71</a> /// avoid busy‑waiting.
|
||||
<a href=#72 id=72 data-nosnippet>72</a> </span><span class="kw">async fn </span>run_loop(<span class="kw-2">&</span><span class="self">self</span>) {
|
||||
<a href=#73 id=73 data-nosnippet>73</a> <span class="macro">println!</span>(<span class="string">"Agent {} starting run loop..."</span>, <span class="self">self</span>.id);
|
||||
<a href=#74 id=74 data-nosnippet>74</a> <span class="kw">loop </span>{
|
||||
<a href=#75 id=75 data-nosnippet>75</a> <span class="kw">match </span><span class="self">self</span>.mailbox.receive_pending(<span class="kw-2">&</span><span class="self">self</span>.id) {
|
||||
<a href=#76 id=76 data-nosnippet>76</a> <span class="prelude-val">Ok</span>(messages) => {
|
||||
<a href=#77 id=77 data-nosnippet>77</a> <span class="kw">for </span>msg <span class="kw">in </span>messages {
|
||||
<a href=#78 id=78 data-nosnippet>78</a> <span class="macro">println!</span>(<span class="string">"Received message: {:?}"</span>, msg.topic);
|
||||
<a href=#79 id=79 data-nosnippet>79</a> <span class="kw">let </span>log_entry = <span class="macro">serde_json::json!</span>({
|
||||
<a href=#80 id=80 data-nosnippet>80</a> <span class="string">"id"</span>: msg.id.to_string(),
|
||||
<a href=#81 id=81 data-nosnippet>81</a> <span class="string">"topic"</span>: msg.topic,
|
||||
<a href=#82 id=82 data-nosnippet>82</a> <span class="string">"payload"</span>: msg.payload.to_string(),
|
||||
<a href=#83 id=83 data-nosnippet>83</a> <span class="string">"received_at"</span>: Utc::now().to_rfc3339()
|
||||
<a href=#84 id=84 data-nosnippet>84</a> });
|
||||
<a href=#85 id=85 data-nosnippet>85</a> <span class="kw">if let </span><span class="prelude-val">Err</span>(e) = <span class="self">self</span>.graph.insert_node(<span class="string">"task_log"</span>, log_entry) {
|
||||
<a href=#86 id=86 data-nosnippet>86</a> <span class="macro">eprintln!</span>(<span class="string">"Failed to log task to graph: {}"</span>, e);
|
||||
<a href=#87 id=87 data-nosnippet>87</a> } <span class="kw">else </span>{
|
||||
<a href=#88 id=88 data-nosnippet>88</a> <span class="kw">let _ </span>= <span class="self">self</span>.graph.commit(<span class="kw-2">&</span><span class="macro">format!</span>(<span class="string">"Logged task: {}"</span>, msg.id));
|
||||
<a href=#89 id=89 data-nosnippet>89</a> <span class="kw">let _ </span>= <span class="self">self</span>.mailbox.mark_read(msg.id);
|
||||
<a href=#90 id=90 data-nosnippet>90</a> }
|
||||
<a href=#91 id=91 data-nosnippet>91</a> }
|
||||
<a href=#92 id=92 data-nosnippet>92</a> }
|
||||
<a href=#93 id=93 data-nosnippet>93</a> <span class="prelude-val">Err</span>(e) => <span class="macro">eprintln!</span>(<span class="string">"Mailbox error: {}"</span>, e),
|
||||
<a href=#94 id=94 data-nosnippet>94</a> }
|
||||
<a href=#95 id=95 data-nosnippet>95</a> sleep(Duration::from_secs(<span class="number">5</span>)).<span class="kw">await</span>;
|
||||
<a href=#96 id=96 data-nosnippet>96</a> }
|
||||
<a href=#97 id=97 data-nosnippet>97</a> }
|
||||
<a href=#98 id=98 data-nosnippet>98</a>}
|
||||
<a href=#99 id=99 data-nosnippet>99</a>
|
||||
<a href=#100 id=100 data-nosnippet>100</a><span class="doccomment">/// Entry point for the CHORUS agent binary.
|
||||
<a href=#101 id=101 data-nosnippet>101</a>///
|
||||
<a href=#102 id=102 data-nosnippet>102</a>/// It creates a data directory under `/home/Tony/rust/projects/reset/CHORUS/data`
|
||||
<a href=#103 id=103 data-nosnippet>103</a>/// (note the capitalised `Tony` matches the original path), initialises the
|
||||
<a href=#104 id=104 data-nosnippet>104</a>/// `CHORUSAgent`, and starts its run loop.
|
||||
<a href=#105 id=105 data-nosnippet>105</a></span><span class="attr">#[tokio::main]
|
||||
<a href=#106 id=106 data-nosnippet>106</a></span><span class="kw">async fn </span>main() -> <span class="prelude-ty">Result</span><(), Box<<span class="kw">dyn </span>std::error::Error>> {
|
||||
<a href=#107 id=107 data-nosnippet>107</a> <span class="kw">let </span>agent_id = <span class="string">"agent-001"</span>;
|
||||
<a href=#108 id=108 data-nosnippet>108</a> <span class="kw">let </span>base_path = Path::new(<span class="string">"/home/Tony/rust/projects/reset/CHORUS/data/agent-001"</span>);
|
||||
<a href=#109 id=109 data-nosnippet>109</a> std::fs::create_dir_all(base_path)<span class="question-mark">?</span>;
|
||||
<a href=#110 id=110 data-nosnippet>110</a>
|
||||
<a href=#111 id=111 data-nosnippet>111</a> <span class="kw">let </span>agent = CHORUSAgent::init(agent_id, base_path).<span class="kw">await</span><span class="question-mark">?</span>;
|
||||
<a href=#112 id=112 data-nosnippet>112</a> agent.run_loop().<span class="kw">await</span>;
|
||||
<a href=#113 id=113 data-nosnippet>113</a>
|
||||
<a href=#114 id=114 data-nosnippet>114</a> <span class="prelude-val">Ok</span>(())
|
||||
<a href=#115 id=115 data-nosnippet>115</a>}</code></pre></div></section></main></body></html>
|
||||
217
target/doc/src/chrs_bubble/lib.rs.html
Normal file
217
target/doc/src/chrs_bubble/lib.rs.html
Normal file
@@ -0,0 +1,217 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `chrs-bubble/src/lib.rs`."><title>lib.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="chrs_bubble" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../../static.files/storage-82c7156e.js"></script><script defer src="../../static.files/src-script-63605ae7.js"></script><script defer src="../../src-files.js"></script><script defer src="../../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer"></div><main><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1><div class="sub-heading">chrs_bubble/</div>lib.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="doccomment">/// # chrs-bubble
|
||||
<a href=#2 id=2 data-nosnippet>2</a>///
|
||||
<a href=#3 id=3 data-nosnippet>3</a>/// A provenance‑tracking crate that records nodes and edges in a directed acyclic
|
||||
<a href=#4 id=4 data-nosnippet>4</a>/// graph (DAG) and persists them using a Dolt‑backed graph implementation.
|
||||
<a href=#5 id=5 data-nosnippet>5</a>/// The crate is deliberately small – it only pulls in `petgraph` for the in‑memory
|
||||
<a href=#6 id=6 data-nosnippet>6</a>/// DAG, `serde` for serialization, `uuid` for unique identifiers and `thiserror`
|
||||
<a href=#7 id=7 data-nosnippet>7</a>/// for ergonomic error handling. It is used by higher‑level components that need
|
||||
<a href=#8 id=8 data-nosnippet>8</a>/// to capture the provenance of generated artifacts (e.g. files, messages, or
|
||||
<a href=#9 id=9 data-nosnippet>9</a>/// results) and later query that history.
|
||||
<a href=#10 id=10 data-nosnippet>10</a>///
|
||||
<a href=#11 id=11 data-nosnippet>11</a>/// The public API is organised around three concepts:
|
||||
<a href=#12 id=12 data-nosnippet>12</a>/// * **ProvenanceEdge** – The type of relationship between two nodes.
|
||||
<a href=#13 id=13 data-nosnippet>13</a>/// * **BubbleError** – Errors that can occur when interacting with the underlying
|
||||
<a href=#14 id=14 data-nosnippet>14</a>/// Dolt graph or when a node cannot be found.
|
||||
<a href=#15 id=15 data-nosnippet>15</a>/// * **ProvenanceGraph** – The façade that holds an in‑memory DAG and a
|
||||
<a href=#16 id=16 data-nosnippet>16</a>/// `DoltGraph` persistence layer, exposing methods to record nodes and links.
|
||||
<a href=#17 id=17 data-nosnippet>17</a>///
|
||||
<a href=#18 id=18 data-nosnippet>18</a>/// Each item is documented with a *WHAT*, *HOW* and *WHY* section so that users can
|
||||
<a href=#19 id=19 data-nosnippet>19</a>/// quickly understand its purpose, its implementation details and the design
|
||||
<a href=#20 id=20 data-nosnippet>20</a>/// rationale.
|
||||
<a href=#21 id=21 data-nosnippet>21</a></span><span class="kw">use </span>chrs_graph::{DoltGraph, GraphError};
|
||||
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">use </span>petgraph::graph::{DiGraph, NodeIndex};
|
||||
<a href=#23 id=23 data-nosnippet>23</a><span class="kw">use </span>serde::{Deserialize, Serialize};
|
||||
<a href=#24 id=24 data-nosnippet>24</a><span class="kw">use </span>std::collections::HashMap;
|
||||
<a href=#25 id=25 data-nosnippet>25</a><span class="kw">use </span>thiserror::Error;
|
||||
<a href=#26 id=26 data-nosnippet>26</a><span class="kw">use </span>ucxl::UCXLAddress;
|
||||
<a href=#27 id=27 data-nosnippet>27</a><span class="kw">use </span>uuid::Uuid;
|
||||
<a href=#28 id=28 data-nosnippet>28</a>
|
||||
<a href=#29 id=29 data-nosnippet>29</a><span class="doccomment">/// Represents the kind of relationship between two provenance nodes.
|
||||
<a href=#30 id=30 data-nosnippet>30</a>///
|
||||
<a href=#31 id=31 data-nosnippet>31</a>/// * **WHAT** – An enumeration of supported edge types. Currently we support:
|
||||
<a href=#32 id=32 data-nosnippet>32</a>/// - `DerivedFrom` – Indicates that the target was derived from the source.
|
||||
<a href=#33 id=33 data-nosnippet>33</a>/// - `Cites` – A citation relationship.
|
||||
<a href=#34 id=34 data-nosnippet>34</a>/// - `InfluencedBy` – Denotes influence without direct derivation.
|
||||
<a href=#35 id=35 data-nosnippet>35</a>/// * **HOW** – Used as the edge payload in the `petgraph::DiGraph`. The enum is
|
||||
<a href=#36 id=36 data-nosnippet>36</a>/// `#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]` so it
|
||||
<a href=#37 id=37 data-nosnippet>37</a>/// can be serialised when persisting the graph.
|
||||
<a href=#38 id=38 data-nosnippet>38</a>/// * **WHY** – Encoding edge semantics as a dedicated enum makes provenance
|
||||
<a href=#39 id=39 data-nosnippet>39</a>/// queries expressive and type‑safe, while keeping the on‑disk representation
|
||||
<a href=#40 id=40 data-nosnippet>40</a>/// simple (a stringified variant).
|
||||
<a href=#41 id=41 data-nosnippet>41</a></span><span class="attr">#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
|
||||
<a href=#42 id=42 data-nosnippet>42</a></span><span class="kw">pub enum </span>ProvenanceEdge {
|
||||
<a href=#43 id=43 data-nosnippet>43</a> <span class="doccomment">/// The target node was *derived* from the source node.
|
||||
<a href=#44 id=44 data-nosnippet>44</a> </span>DerivedFrom,
|
||||
<a href=#45 id=45 data-nosnippet>45</a> <span class="doccomment">/// The target node *cites* the source node.
|
||||
<a href=#46 id=46 data-nosnippet>46</a> </span>Cites,
|
||||
<a href=#47 id=47 data-nosnippet>47</a> <span class="doccomment">/// The target node was *influenced* by the source node.
|
||||
<a href=#48 id=48 data-nosnippet>48</a> </span>InfluencedBy,
|
||||
<a href=#49 id=49 data-nosnippet>49</a>}
|
||||
<a href=#50 id=50 data-nosnippet>50</a>
|
||||
<a href=#51 id=51 data-nosnippet>51</a><span class="doccomment">/// Errors that can arise when working with a `ProvenanceGraph`.
|
||||
<a href=#52 id=52 data-nosnippet>52</a>///
|
||||
<a href=#53 id=53 data-nosnippet>53</a>/// * **WHAT** – Enumerates possible failure modes:
|
||||
<a href=#54 id=54 data-nosnippet>54</a>/// - Graph‑level errors (`GraphError`).
|
||||
<a href=#55 id=55 data-nosnippet>55</a>/// - Serde JSON errors (`serde_json::Error`).
|
||||
<a href=#56 id=56 data-nosnippet>56</a>/// - A lookup failure when a node identifier cannot be resolved.
|
||||
<a href=#57 id=57 data-nosnippet>57</a>/// * **HOW** – Implements `std::error::Error` via the `thiserror::Error` derive
|
||||
<a href=#58 id=58 data-nosnippet>58</a>/// macro, forwarding underlying error sources with `#[from]`.
|
||||
<a href=#59 id=59 data-nosnippet>59</a>/// * **WHY** – A single error type simplifies error propagation for callers and
|
||||
<a href=#60 id=60 data-nosnippet>60</a>/// retains the original context for debugging.
|
||||
<a href=#61 id=61 data-nosnippet>61</a></span><span class="attr">#[derive(Debug, Error)]
|
||||
<a href=#62 id=62 data-nosnippet>62</a></span><span class="kw">pub enum </span>BubbleError {
|
||||
<a href=#63 id=63 data-nosnippet>63</a> <span class="attr">#[error(<span class="string">"Graph error: {0}"</span>)]
|
||||
<a href=#64 id=64 data-nosnippet>64</a> </span>Graph(<span class="attr">#[from] </span>GraphError),
|
||||
<a href=#65 id=65 data-nosnippet>65</a> <span class="attr">#[error(<span class="string">"Serde error: {0}"</span>)]
|
||||
<a href=#66 id=66 data-nosnippet>66</a> </span>Serde(<span class="attr">#[from] </span>serde_json::Error),
|
||||
<a href=#67 id=67 data-nosnippet>67</a> <span class="attr">#[error(<span class="string">"Node not found: {0}"</span>)]
|
||||
<a href=#68 id=68 data-nosnippet>68</a> </span>NodeNotFound(Uuid),
|
||||
<a href=#69 id=69 data-nosnippet>69</a>}
|
||||
<a href=#70 id=70 data-nosnippet>70</a>
|
||||
<a href=#71 id=71 data-nosnippet>71</a><span class="doccomment">/// Core structure that maintains an in‑memory DAG of provenance nodes and a
|
||||
<a href=#72 id=72 data-nosnippet>72</a>/// persistent `DoltGraph` backend.
|
||||
<a href=#73 id=73 data-nosnippet>73</a>///
|
||||
<a href=#74 id=74 data-nosnippet>74</a>/// * **WHAT** – Holds:
|
||||
<a href=#75 id=75 data-nosnippet>75</a>/// - `persistence`: The Dolt‑based storage implementation.
|
||||
<a href=#76 id=76 data-nosnippet>76</a>/// - `dag`: A `petgraph::DiGraph` where node payloads are UUIDs and edges are
|
||||
<a href=#77 id=77 data-nosnippet>77</a>/// `ProvenanceEdge`s.
|
||||
<a href=#78 id=78 data-nosnippet>78</a>/// - `node_map`: A fast lookup map from node UUID to the corresponding
|
||||
<a href=#79 id=79 data-nosnippet>79</a>/// `petgraph::NodeIndex`.
|
||||
<a href=#80 id=80 data-nosnippet>80</a>/// * **HOW** – Provides methods to create nodes (`record_node`) and edges
|
||||
<a href=#81 id=81 data-nosnippet>81</a>/// (`record_link`). These methods insert into the in‑memory graph and then
|
||||
<a href=#82 id=82 data-nosnippet>82</a>/// persist the data in Dolt tables using simple `INSERT` statements followed by
|
||||
<a href=#83 id=83 data-nosnippet>83</a>/// a `commit`.
|
||||
<a href=#84 id=84 data-nosnippet>84</a>/// * **WHY** – Separating the transient in‑memory representation from durable
|
||||
<a href=#85 id=85 data-nosnippet>85</a>/// storage gives fast runtime queries while guaranteeing that the provenance
|
||||
<a href=#86 id=86 data-nosnippet>86</a>/// graph can survive process restarts and be inspected via Dolt tools.
|
||||
<a href=#87 id=87 data-nosnippet>87</a></span><span class="kw">pub struct </span>ProvenanceGraph {
|
||||
<a href=#88 id=88 data-nosnippet>88</a> persistence: DoltGraph,
|
||||
<a href=#89 id=89 data-nosnippet>89</a> dag: DiGraph<Uuid, ProvenanceEdge>,
|
||||
<a href=#90 id=90 data-nosnippet>90</a> node_map: HashMap<Uuid, NodeIndex>,
|
||||
<a href=#91 id=91 data-nosnippet>91</a>}
|
||||
<a href=#92 id=92 data-nosnippet>92</a>
|
||||
<a href=#93 id=93 data-nosnippet>93</a><span class="kw">impl </span>ProvenanceGraph {
|
||||
<a href=#94 id=94 data-nosnippet>94</a> <span class="doccomment">/// Creates a new `ProvenanceGraph` backed by a pre‑initialised `DoltGraph`.
|
||||
<a href=#95 id=95 data-nosnippet>95</a> ///
|
||||
<a href=#96 id=96 data-nosnippet>96</a> /// * **WHAT** – Returns a fresh instance with empty in‑memory structures.
|
||||
<a href=#97 id=97 data-nosnippet>97</a> /// * **HOW** – Stores the supplied `persistence` and constructs a new `DiGraph`
|
||||
<a href=#98 id=98 data-nosnippet>98</a> /// and empty `HashMap`.
|
||||
<a href=#99 id=99 data-nosnippet>99</a> /// * **WHY** – Allows callers to decide where the Dolt repository lives (e.g.
|
||||
<a href=#100 id=100 data-nosnippet>100</a> /// a temporary directory for tests or a permanent location for production).
|
||||
<a href=#101 id=101 data-nosnippet>101</a> </span><span class="kw">pub fn </span>new(persistence: DoltGraph) -> <span class="self">Self </span>{
|
||||
<a href=#102 id=102 data-nosnippet>102</a> <span class="self">Self </span>{
|
||||
<a href=#103 id=103 data-nosnippet>103</a> persistence,
|
||||
<a href=#104 id=104 data-nosnippet>104</a> dag: DiGraph::new(),
|
||||
<a href=#105 id=105 data-nosnippet>105</a> node_map: HashMap::new(),
|
||||
<a href=#106 id=106 data-nosnippet>106</a> }
|
||||
<a href=#107 id=107 data-nosnippet>107</a> }
|
||||
<a href=#108 id=108 data-nosnippet>108</a>
|
||||
<a href=#109 id=109 data-nosnippet>109</a> <span class="doccomment">/// Records a provenance node with a unique `Uuid` and an associated address.
|
||||
<a href=#110 id=110 data-nosnippet>110</a> ///
|
||||
<a href=#111 id=111 data-nosnippet>111</a> /// * **WHAT** – Persists the node both in‑memory (`dag` + `node_map`) and in a
|
||||
<a href=#112 id=112 data-nosnippet>112</a> /// Dolt table called `provenance_nodes`.
|
||||
<a href=#113 id=113 data-nosnippet>113</a> /// * **HOW** – If the node does not already exist, it is added to the DAG and a
|
||||
<a href=#114 id=114 data-nosnippet>114</a> /// row is inserted via `persistence.insert_node`. A commit is performed with a
|
||||
<a href=#115 id=115 data-nosnippet>115</a> /// descriptive message.
|
||||
<a href=#116 id=116 data-nosnippet>116</a> /// * **WHY** – Storing the address (typically a UCXL address) allows later
|
||||
<a href=#117 id=117 data-nosnippet>117</a> /// resolution of where the artifact originated.
|
||||
<a href=#118 id=118 data-nosnippet>118</a> </span><span class="kw">pub fn </span>record_node(<span class="kw-2">&mut </span><span class="self">self</span>, id: Uuid, address: <span class="kw-2">&</span>str) -> <span class="prelude-ty">Result</span><(), BubbleError> {
|
||||
<a href=#119 id=119 data-nosnippet>119</a> <span class="kw">if </span>!<span class="self">self</span>.node_map.contains_key(<span class="kw-2">&</span>id) {
|
||||
<a href=#120 id=120 data-nosnippet>120</a> <span class="kw">let </span>idx = <span class="self">self</span>.dag.add_node(id);
|
||||
<a href=#121 id=121 data-nosnippet>121</a> <span class="self">self</span>.node_map.insert(id, idx);
|
||||
<a href=#122 id=122 data-nosnippet>122</a>
|
||||
<a href=#123 id=123 data-nosnippet>123</a> <span class="comment">// Ensure the backing table exists – ignore errors if it already does.
|
||||
<a href=#124 id=124 data-nosnippet>124</a> </span><span class="self">self</span>.persistence
|
||||
<a href=#125 id=125 data-nosnippet>125</a> .create_table(
|
||||
<a href=#126 id=126 data-nosnippet>126</a> <span class="string">"provenance_nodes"</span>,
|
||||
<a href=#127 id=127 data-nosnippet>127</a> <span class="string">"id VARCHAR(255) PRIMARY KEY, address TEXT"</span>,
|
||||
<a href=#128 id=128 data-nosnippet>128</a> )
|
||||
<a href=#129 id=129 data-nosnippet>129</a> .ok();
|
||||
<a href=#130 id=130 data-nosnippet>130</a>
|
||||
<a href=#131 id=131 data-nosnippet>131</a> <span class="kw">let </span>data = <span class="macro">serde_json::json!</span>({
|
||||
<a href=#132 id=132 data-nosnippet>132</a> <span class="string">"id"</span>: id.to_string(),
|
||||
<a href=#133 id=133 data-nosnippet>133</a> <span class="string">"address"</span>: address,
|
||||
<a href=#134 id=134 data-nosnippet>134</a> });
|
||||
<a href=#135 id=135 data-nosnippet>135</a> <span class="self">self</span>.persistence.insert_node(<span class="string">"provenance_nodes"</span>, data)<span class="question-mark">?</span>;
|
||||
<a href=#136 id=136 data-nosnippet>136</a> <span class="self">self</span>.persistence
|
||||
<a href=#137 id=137 data-nosnippet>137</a> .commit(<span class="kw-2">&</span><span class="macro">format!</span>(<span class="string">"Record provenance node: {}"</span>, id))<span class="question-mark">?</span>;
|
||||
<a href=#138 id=138 data-nosnippet>138</a> }
|
||||
<a href=#139 id=139 data-nosnippet>139</a> <span class="prelude-val">Ok</span>(())
|
||||
<a href=#140 id=140 data-nosnippet>140</a> }
|
||||
<a href=#141 id=141 data-nosnippet>141</a>
|
||||
<a href=#142 id=142 data-nosnippet>142</a> <span class="doccomment">/// Records a directed edge between two existing nodes.
|
||||
<a href=#143 id=143 data-nosnippet>143</a> ///
|
||||
<a href=#144 id=144 data-nosnippet>144</a> /// * **WHAT** – Adds an edge of type `ProvenanceEdge` to the DAG and stores a
|
||||
<a href=#145 id=145 data-nosnippet>145</a> /// corresponding row in the `provenance_links` Dolt table.
|
||||
<a href=#146 id=146 data-nosnippet>146</a> /// * **HOW** – Retrieves the `NodeIndex` for each UUID (erroring with
|
||||
<a href=#147 id=147 data-nosnippet>147</a> /// `BubbleError::NodeNotFound` if missing), adds the edge to `dag`, then
|
||||
<a href=#148 id=148 data-nosnippet>148</a> /// inserts a row containing a new link UUID, source/target IDs and the edge
|
||||
<a href=#149 id=149 data-nosnippet>149</a> /// type as a string.
|
||||
<a href=#150 id=150 data-nosnippet>150</a> /// * **WHY** – Persisting links allows the full provenance graph to be queried
|
||||
<a href=#151 id=151 data-nosnippet>151</a> /// outside the process, while the in‑memory representation keeps runtime
|
||||
<a href=#152 id=152 data-nosnippet>152</a> /// operations cheap.
|
||||
<a href=#153 id=153 data-nosnippet>153</a> </span><span class="kw">pub fn </span>record_link(
|
||||
<a href=#154 id=154 data-nosnippet>154</a> <span class="kw-2">&mut </span><span class="self">self</span>,
|
||||
<a href=#155 id=155 data-nosnippet>155</a> source: Uuid,
|
||||
<a href=#156 id=156 data-nosnippet>156</a> target: Uuid,
|
||||
<a href=#157 id=157 data-nosnippet>157</a> edge: ProvenanceEdge,
|
||||
<a href=#158 id=158 data-nosnippet>158</a> ) -> <span class="prelude-ty">Result</span><(), BubbleError> {
|
||||
<a href=#159 id=159 data-nosnippet>159</a> <span class="kw">let </span>source_idx = <span class="kw-2">*</span><span class="self">self
|
||||
<a href=#160 id=160 data-nosnippet>160</a> </span>.node_map
|
||||
<a href=#161 id=161 data-nosnippet>161</a> .get(<span class="kw-2">&</span>source)
|
||||
<a href=#162 id=162 data-nosnippet>162</a> .ok_or(BubbleError::NodeNotFound(source))<span class="question-mark">?</span>;
|
||||
<a href=#163 id=163 data-nosnippet>163</a> <span class="kw">let </span>target_idx = <span class="kw-2">*</span><span class="self">self
|
||||
<a href=#164 id=164 data-nosnippet>164</a> </span>.node_map
|
||||
<a href=#165 id=165 data-nosnippet>165</a> .get(<span class="kw-2">&</span>target)
|
||||
<a href=#166 id=166 data-nosnippet>166</a> .ok_or(BubbleError::NodeNotFound(target))<span class="question-mark">?</span>;
|
||||
<a href=#167 id=167 data-nosnippet>167</a>
|
||||
<a href=#168 id=168 data-nosnippet>168</a> <span class="self">self</span>.dag.add_edge(source_idx, target_idx, edge);
|
||||
<a href=#169 id=169 data-nosnippet>169</a>
|
||||
<a href=#170 id=170 data-nosnippet>170</a> <span class="comment">// Ensure the links table exists.
|
||||
<a href=#171 id=171 data-nosnippet>171</a> </span><span class="self">self</span>.persistence
|
||||
<a href=#172 id=172 data-nosnippet>172</a> .create_table(
|
||||
<a href=#173 id=173 data-nosnippet>173</a> <span class="string">"provenance_links"</span>,
|
||||
<a href=#174 id=174 data-nosnippet>174</a> <span class="string">"id VARCHAR(255) PRIMARY KEY, source_id TEXT, target_id TEXT, edge_type TEXT"</span>,
|
||||
<a href=#175 id=175 data-nosnippet>175</a> )
|
||||
<a href=#176 id=176 data-nosnippet>176</a> .ok();
|
||||
<a href=#177 id=177 data-nosnippet>177</a>
|
||||
<a href=#178 id=178 data-nosnippet>178</a> <span class="kw">let </span>link_id = Uuid::new_v4();
|
||||
<a href=#179 id=179 data-nosnippet>179</a> <span class="kw">let </span>data = <span class="macro">serde_json::json!</span>({
|
||||
<a href=#180 id=180 data-nosnippet>180</a> <span class="string">"id"</span>: link_id.to_string(),
|
||||
<a href=#181 id=181 data-nosnippet>181</a> <span class="string">"source_id"</span>: source.to_string(),
|
||||
<a href=#182 id=182 data-nosnippet>182</a> <span class="string">"target_id"</span>: target.to_string(),
|
||||
<a href=#183 id=183 data-nosnippet>183</a> <span class="string">"edge_type"</span>: <span class="macro">format!</span>(<span class="string">"{:?}"</span>, edge),
|
||||
<a href=#184 id=184 data-nosnippet>184</a> });
|
||||
<a href=#185 id=185 data-nosnippet>185</a> <span class="self">self</span>.persistence.insert_node(<span class="string">"provenance_links"</span>, data)<span class="question-mark">?</span>;
|
||||
<a href=#186 id=186 data-nosnippet>186</a> <span class="self">self</span>.persistence
|
||||
<a href=#187 id=187 data-nosnippet>187</a> .commit(<span class="kw-2">&</span><span class="macro">format!</span>(<span class="string">"Record provenance link: {} -> {}"</span>, source, target))<span class="question-mark">?</span>;
|
||||
<a href=#188 id=188 data-nosnippet>188</a> <span class="prelude-val">Ok</span>(())
|
||||
<a href=#189 id=189 data-nosnippet>189</a> }
|
||||
<a href=#190 id=190 data-nosnippet>190</a>}
|
||||
<a href=#191 id=191 data-nosnippet>191</a>
|
||||
<a href=#192 id=192 data-nosnippet>192</a><span class="attr">#[cfg(test)]
|
||||
<a href=#193 id=193 data-nosnippet>193</a></span><span class="kw">mod </span>tests {
|
||||
<a href=#194 id=194 data-nosnippet>194</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
|
||||
<a href=#195 id=195 data-nosnippet>195</a> <span class="kw">use </span>tempfile::TempDir;
|
||||
<a href=#196 id=196 data-nosnippet>196</a>
|
||||
<a href=#197 id=197 data-nosnippet>197</a> <span class="attr">#[test]
|
||||
<a href=#198 id=198 data-nosnippet>198</a> </span><span class="kw">fn </span>test_provenance_dag() {
|
||||
<a href=#199 id=199 data-nosnippet>199</a> <span class="kw">let </span>dir = TempDir::new().unwrap();
|
||||
<a href=#200 id=200 data-nosnippet>200</a> <span class="kw">let </span>persistence = DoltGraph::init(dir.path()).expect(<span class="string">"dolt init failed"</span>);
|
||||
<a href=#201 id=201 data-nosnippet>201</a> <span class="kw">let </span><span class="kw-2">mut </span>graph = ProvenanceGraph::new(persistence);
|
||||
<a href=#202 id=202 data-nosnippet>202</a>
|
||||
<a href=#203 id=203 data-nosnippet>203</a> <span class="kw">let </span>id1 = Uuid::new_v4();
|
||||
<a href=#204 id=204 data-nosnippet>204</a> <span class="kw">let </span>id2 = Uuid::new_v4();
|
||||
<a href=#205 id=205 data-nosnippet>205</a>
|
||||
<a href=#206 id=206 data-nosnippet>206</a> graph
|
||||
<a href=#207 id=207 data-nosnippet>207</a> .record_node(id1, <span class="string">"ucxl://agent:1@proj:task/#/file1.txt"</span>)
|
||||
<a href=#208 id=208 data-nosnippet>208</a> .unwrap();
|
||||
<a href=#209 id=209 data-nosnippet>209</a> graph
|
||||
<a href=#210 id=210 data-nosnippet>210</a> .record_node(id2, <span class="string">"ucxl://agent:1@proj:task/#/file2.txt"</span>)
|
||||
<a href=#211 id=211 data-nosnippet>211</a> .unwrap();
|
||||
<a href=#212 id=212 data-nosnippet>212</a>
|
||||
<a href=#213 id=213 data-nosnippet>213</a> graph
|
||||
<a href=#214 id=214 data-nosnippet>214</a> .record_link(id1, id2, ProvenanceEdge::DerivedFrom)
|
||||
<a href=#215 id=215 data-nosnippet>215</a> .unwrap();
|
||||
<a href=#216 id=216 data-nosnippet>216</a> }
|
||||
<a href=#217 id=217 data-nosnippet>217</a>}</code></pre></div></section></main></body></html>
|
||||
167
target/doc/src/chrs_graph/lib.rs.html
Normal file
167
target/doc/src/chrs_graph/lib.rs.html
Normal file
@@ -0,0 +1,167 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `chrs-graph/src/lib.rs`."><title>lib.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="chrs_graph" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../../static.files/storage-82c7156e.js"></script><script defer src="../../static.files/src-script-63605ae7.js"></script><script defer src="../../src-files.js"></script><script defer src="../../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer"></div><main><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1><div class="sub-heading">chrs_graph/</div>lib.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="doccomment">//! chrs-graph library implementation using Dolt for graph persistence.
|
||||
<a href=#2 id=2 data-nosnippet>2</a>
|
||||
<a href=#3 id=3 data-nosnippet>3</a></span><span class="kw">use </span>chrono::Utc;
|
||||
<a href=#4 id=4 data-nosnippet>4</a><span class="kw">use </span>serde_json::Value;
|
||||
<a href=#5 id=5 data-nosnippet>5</a><span class="kw">use </span>std::{path::Path, process::Command};
|
||||
<a href=#6 id=6 data-nosnippet>6</a><span class="kw">use </span>thiserror::Error;
|
||||
<a href=#7 id=7 data-nosnippet>7</a><span class="kw">use </span>uuid::Uuid;
|
||||
<a href=#8 id=8 data-nosnippet>8</a>
|
||||
<a href=#9 id=9 data-nosnippet>9</a><span class="doccomment">/// Enumeration of possible errors that can arise while interacting with the `DoltGraph`.
|
||||
<a href=#10 id=10 data-nosnippet>10</a>///
|
||||
<a href=#11 id=11 data-nosnippet>11</a>/// Each variant wraps an underlying error source, making it easier for callers to
|
||||
<a href=#12 id=12 data-nosnippet>12</a>/// understand the failure context and decide on remedial actions.
|
||||
<a href=#13 id=13 data-nosnippet>13</a></span><span class="attr">#[derive(Error, Debug)]
|
||||
<a href=#14 id=14 data-nosnippet>14</a></span><span class="kw">pub enum </span>GraphError {
|
||||
<a href=#15 id=15 data-nosnippet>15</a> <span class="doccomment">/// Propagates I/O errors from the standard library (e.g., filesystem access).
|
||||
<a href=#16 id=16 data-nosnippet>16</a> </span><span class="attr">#[error(<span class="string">"IO error: {0}"</span>)]
|
||||
<a href=#17 id=17 data-nosnippet>17</a> </span>Io(<span class="attr">#[from] </span>std::io::Error),
|
||||
<a href=#18 id=18 data-nosnippet>18</a> <span class="doccomment">/// Represents a failure when executing a Dolt command.
|
||||
<a href=#19 id=19 data-nosnippet>19</a> </span><span class="attr">#[error(<span class="string">"Command failed: {0}"</span>)]
|
||||
<a href=#20 id=20 data-nosnippet>20</a> </span>CommandFailed(String),
|
||||
<a href=#21 id=21 data-nosnippet>21</a> <span class="doccomment">/// Propagates JSON (de)serialization errors from `serde_json`.
|
||||
<a href=#22 id=22 data-nosnippet>22</a> </span><span class="attr">#[error(<span class="string">"Serde JSON error: {0}"</span>)]
|
||||
<a href=#23 id=23 data-nosnippet>23</a> </span>SerdeJson(<span class="attr">#[from] </span>serde_json::Error),
|
||||
<a href=#24 id=24 data-nosnippet>24</a> <span class="doccomment">/// A generic catch‑all for errors that don't fit the other categories.
|
||||
<a href=#25 id=25 data-nosnippet>25</a> </span><span class="attr">#[error(<span class="string">"Other error: {0}"</span>)]
|
||||
<a href=#26 id=26 data-nosnippet>26</a> </span>Other(String),
|
||||
<a href=#27 id=27 data-nosnippet>27</a>}
|
||||
<a href=#28 id=28 data-nosnippet>28</a>
|
||||
<a href=#29 id=29 data-nosnippet>29</a><span class="doccomment">/// Wrapper around a Dolt repository that stores graph data.
|
||||
<a href=#30 id=30 data-nosnippet>30</a>///
|
||||
<a href=#31 id=31 data-nosnippet>31</a>/// The `DoltGraph` type encapsulates a path to a Dolt repo and provides high‑level
|
||||
<a href=#32 id=32 data-nosnippet>32</a>/// operations such as initializing the repo, committing changes, creating tables, and
|
||||
<a href=#33 id=33 data-nosnippet>33</a>/// inserting nodes expressed as JSON objects.
|
||||
<a href=#34 id=34 data-nosnippet>34</a>///
|
||||
<a href=#35 id=35 data-nosnippet>35</a>/// # Architectural Rationale
|
||||
<a href=#36 id=36 data-nosnippet>36</a>/// Dolt offers a Git‑like version‑controlled SQL database, which aligns well with CHORUS's
|
||||
<a href=#37 id=37 data-nosnippet>37</a>/// need for an immutable, query‑able history of graph mutations. By wrapping Dolt commands in
|
||||
<a href=#38 id=38 data-nosnippet>38</a>/// this struct we isolate the rest of the codebase from the command‑line interface, making the
|
||||
<a href=#39 id=39 data-nosnippet>39</a>/// graph layer portable and easier to test.
|
||||
<a href=#40 id=40 data-nosnippet>40</a></span><span class="kw">pub struct </span>DoltGraph {
|
||||
<a href=#41 id=41 data-nosnippet>41</a> <span class="doccomment">/// Filesystem path to the root of the Dolt repository.
|
||||
<a href=#42 id=42 data-nosnippet>42</a> </span><span class="kw">pub </span>repo_path: std::path::PathBuf,
|
||||
<a href=#43 id=43 data-nosnippet>43</a>}
|
||||
<a href=#44 id=44 data-nosnippet>44</a>
|
||||
<a href=#45 id=45 data-nosnippet>45</a><span class="kw">impl </span>DoltGraph {
|
||||
<a href=#46 id=46 data-nosnippet>46</a> <span class="doccomment">/// Initialise (or open) a Dolt repository at the given `path`.
|
||||
<a href=#47 id=47 data-nosnippet>47</a> ///
|
||||
<a href=#48 id=48 data-nosnippet>48</a> /// If the directory does not already contain a `.dolt` sub‑directory, the function runs
|
||||
<a href=#49 id=49 data-nosnippet>49</a> /// `dolt init` to create a new repository. Errors from the underlying command are wrapped in
|
||||
<a href=#50 id=50 data-nosnippet>50</a> /// `GraphError::CommandFailed`.
|
||||
<a href=#51 id=51 data-nosnippet>51</a> </span><span class="kw">pub fn </span>init(path: <span class="kw-2">&</span>Path) -> <span class="prelude-ty">Result</span><<span class="self">Self</span>, GraphError> {
|
||||
<a href=#52 id=52 data-nosnippet>52</a> <span class="kw">if </span>!path.join(<span class="string">".dolt"</span>).exists() {
|
||||
<a href=#53 id=53 data-nosnippet>53</a> <span class="kw">let </span>status = Command::new(<span class="string">"dolt"</span>)
|
||||
<a href=#54 id=54 data-nosnippet>54</a> .arg(<span class="string">"init"</span>)
|
||||
<a href=#55 id=55 data-nosnippet>55</a> .current_dir(path)
|
||||
<a href=#56 id=56 data-nosnippet>56</a> .status()<span class="question-mark">?</span>;
|
||||
<a href=#57 id=57 data-nosnippet>57</a> <span class="kw">if </span>!status.success() {
|
||||
<a href=#58 id=58 data-nosnippet>58</a> <span class="kw">return </span><span class="prelude-val">Err</span>(GraphError::CommandFailed(<span class="macro">format!</span>(
|
||||
<a href=#59 id=59 data-nosnippet>59</a> <span class="string">"dolt init failed with status {:?}"</span>,
|
||||
<a href=#60 id=60 data-nosnippet>60</a> status
|
||||
<a href=#61 id=61 data-nosnippet>61</a> )));
|
||||
<a href=#62 id=62 data-nosnippet>62</a> }
|
||||
<a href=#63 id=63 data-nosnippet>63</a> }
|
||||
<a href=#64 id=64 data-nosnippet>64</a> <span class="prelude-val">Ok</span>(<span class="self">Self </span>{
|
||||
<a href=#65 id=65 data-nosnippet>65</a> repo_path: path.to_path_buf(),
|
||||
<a href=#66 id=66 data-nosnippet>66</a> })
|
||||
<a href=#67 id=67 data-nosnippet>67</a> }
|
||||
<a href=#68 id=68 data-nosnippet>68</a>
|
||||
<a href=#69 id=69 data-nosnippet>69</a> <span class="doccomment">/// Execute a Dolt command with the specified arguments.
|
||||
<a href=#70 id=70 data-nosnippet>70</a> ///
|
||||
<a href=#71 id=71 data-nosnippet>71</a> /// This helper centralises command execution and error handling. It runs `dolt` with the
|
||||
<a href=#72 id=72 data-nosnippet>72</a> /// provided argument slice, captures stdout/stderr, and returns `GraphError::CommandFailed`
|
||||
<a href=#73 id=73 data-nosnippet>73</a> /// when the command exits with a non‑zero status.
|
||||
<a href=#74 id=74 data-nosnippet>74</a> </span><span class="kw">fn </span>run_cmd(<span class="kw-2">&</span><span class="self">self</span>, args: <span class="kw-2">&</span>[<span class="kw-2">&</span>str]) -> <span class="prelude-ty">Result</span><(), GraphError> {
|
||||
<a href=#75 id=75 data-nosnippet>75</a> <span class="kw">let </span>output = Command::new(<span class="string">"dolt"</span>)
|
||||
<a href=#76 id=76 data-nosnippet>76</a> .args(args)
|
||||
<a href=#77 id=77 data-nosnippet>77</a> .current_dir(<span class="kw-2">&</span><span class="self">self</span>.repo_path)
|
||||
<a href=#78 id=78 data-nosnippet>78</a> .output()<span class="question-mark">?</span>;
|
||||
<a href=#79 id=79 data-nosnippet>79</a> <span class="kw">if </span>!output.status.success() {
|
||||
<a href=#80 id=80 data-nosnippet>80</a> <span class="kw">let </span>stderr = String::from_utf8_lossy(<span class="kw-2">&</span>output.stderr);
|
||||
<a href=#81 id=81 data-nosnippet>81</a> <span class="kw">return </span><span class="prelude-val">Err</span>(GraphError::CommandFailed(stderr.to_string()));
|
||||
<a href=#82 id=82 data-nosnippet>82</a> }
|
||||
<a href=#83 id=83 data-nosnippet>83</a> <span class="prelude-val">Ok</span>(())
|
||||
<a href=#84 id=84 data-nosnippet>84</a> }
|
||||
<a href=#85 id=85 data-nosnippet>85</a>
|
||||
<a href=#86 id=86 data-nosnippet>86</a> <span class="doccomment">/// Stage all changes and commit them with the provided `message`.
|
||||
<a href=#87 id=87 data-nosnippet>87</a> ///
|
||||
<a href=#88 id=88 data-nosnippet>88</a> /// The method first runs `dolt add -A` to stage modifications, then `dolt commit -m`.
|
||||
<a href=#89 id=89 data-nosnippet>89</a> /// Any failure in these steps propagates as a `GraphError`.
|
||||
<a href=#90 id=90 data-nosnippet>90</a> </span><span class="kw">pub fn </span>commit(<span class="kw-2">&</span><span class="self">self</span>, message: <span class="kw-2">&</span>str) -> <span class="prelude-ty">Result</span><(), GraphError> {
|
||||
<a href=#91 id=91 data-nosnippet>91</a> <span class="self">self</span>.run_cmd(<span class="kw-2">&</span>[<span class="string">"add"</span>, <span class="string">"-A"</span>])<span class="question-mark">?</span>;
|
||||
<a href=#92 id=92 data-nosnippet>92</a> <span class="self">self</span>.run_cmd(<span class="kw-2">&</span>[<span class="string">"commit"</span>, <span class="string">"-m"</span>, message])<span class="question-mark">?</span>;
|
||||
<a href=#93 id=93 data-nosnippet>93</a> <span class="prelude-val">Ok</span>(())
|
||||
<a href=#94 id=94 data-nosnippet>94</a> }
|
||||
<a href=#95 id=95 data-nosnippet>95</a>
|
||||
<a href=#96 id=96 data-nosnippet>96</a> <span class="doccomment">/// Create a SQL table within the Dolt repository.
|
||||
<a href=#97 id=97 data-nosnippet>97</a> ///
|
||||
<a href=#98 id=98 data-nosnippet>98</a> /// `schema` should be a comma‑separated column definition list (e.g., `"id INT PRIMARY KEY, name TEXT"`).
|
||||
<a href=#99 id=99 data-nosnippet>99</a> /// If the table already exists, the function treats it as a no‑op and returns `Ok(())`.
|
||||
<a href=#100 id=100 data-nosnippet>100</a> </span><span class="kw">pub fn </span>create_table(<span class="kw-2">&</span><span class="self">self</span>, table_name: <span class="kw-2">&</span>str, schema: <span class="kw-2">&</span>str) -> <span class="prelude-ty">Result</span><(), GraphError> {
|
||||
<a href=#101 id=101 data-nosnippet>101</a> <span class="kw">let </span>query = <span class="macro">format!</span>(<span class="string">"CREATE TABLE {} ({})"</span>, table_name, schema);
|
||||
<a href=#102 id=102 data-nosnippet>102</a> <span class="kw">if let </span><span class="prelude-val">Err</span>(e) = <span class="self">self</span>.run_cmd(<span class="kw-2">&</span>[<span class="string">"sql"</span>, <span class="string">"-q"</span>, <span class="kw-2">&</span>query]) {
|
||||
<a href=#103 id=103 data-nosnippet>103</a> <span class="kw">if </span>e.to_string().contains(<span class="string">"already exists"</span>) {
|
||||
<a href=#104 id=104 data-nosnippet>104</a> <span class="comment">// Table is already present – not an error for our use‑case.
|
||||
<a href=#105 id=105 data-nosnippet>105</a> </span><span class="kw">return </span><span class="prelude-val">Ok</span>(());
|
||||
<a href=#106 id=106 data-nosnippet>106</a> }
|
||||
<a href=#107 id=107 data-nosnippet>107</a> <span class="kw">return </span><span class="prelude-val">Err</span>(e);
|
||||
<a href=#108 id=108 data-nosnippet>108</a> }
|
||||
<a href=#109 id=109 data-nosnippet>109</a> <span class="self">self</span>.commit(<span class="kw-2">&</span><span class="macro">format!</span>(<span class="string">"Create table {}"</span>, table_name))<span class="question-mark">?</span>;
|
||||
<a href=#110 id=110 data-nosnippet>110</a> <span class="prelude-val">Ok</span>(())
|
||||
<a href=#111 id=111 data-nosnippet>111</a> }
|
||||
<a href=#112 id=112 data-nosnippet>112</a>
|
||||
<a href=#113 id=113 data-nosnippet>113</a> <span class="doccomment">/// Insert a node represented by a JSON object into the specified `table`.
|
||||
<a href=#114 id=114 data-nosnippet>114</a> ///
|
||||
<a href=#115 id=115 data-nosnippet>115</a> /// The JSON `data` must be an object where keys correspond to column names. Supported value
|
||||
<a href=#116 id=116 data-nosnippet>116</a> /// types are strings, numbers, booleans, and null. Complex JSON structures are rejected because
|
||||
<a href=#117 id=117 data-nosnippet>117</a> /// they cannot be directly mapped to SQL scalar columns.
|
||||
<a href=#118 id=118 data-nosnippet>118</a> </span><span class="kw">pub fn </span>insert_node(<span class="kw-2">&</span><span class="self">self</span>, table: <span class="kw-2">&</span>str, data: Value) -> <span class="prelude-ty">Result</span><(), GraphError> {
|
||||
<a href=#119 id=119 data-nosnippet>119</a> <span class="kw">let </span>obj = data
|
||||
<a href=#120 id=120 data-nosnippet>120</a> .as_object()
|
||||
<a href=#121 id=121 data-nosnippet>121</a> .ok_or_else(|| GraphError::Other(<span class="string">"Data must be a JSON object"</span>.into()))<span class="question-mark">?</span>;
|
||||
<a href=#122 id=122 data-nosnippet>122</a> <span class="kw">let </span>columns: Vec<String> = obj.keys().cloned().collect();
|
||||
<a href=#123 id=123 data-nosnippet>123</a> <span class="kw">let </span><span class="kw-2">mut </span>values: Vec<String> = Vec::new();
|
||||
<a href=#124 id=124 data-nosnippet>124</a> <span class="kw">for </span>key <span class="kw">in </span><span class="kw-2">&</span>columns {
|
||||
<a href=#125 id=125 data-nosnippet>125</a> <span class="kw">let </span>v = <span class="kw-2">&</span>obj[key];
|
||||
<a href=#126 id=126 data-nosnippet>126</a> <span class="kw">let </span>sql_val = <span class="kw">match </span>v {
|
||||
<a href=#127 id=127 data-nosnippet>127</a> Value::String(s) => <span class="macro">format!</span>(<span class="string">"'{}'"</span>, s.replace(<span class="string">'\''</span>, <span class="string">"''"</span>)),
|
||||
<a href=#128 id=128 data-nosnippet>128</a> Value::Number(n) => n.to_string(),
|
||||
<a href=#129 id=129 data-nosnippet>129</a> Value::Bool(b) => {
|
||||
<a href=#130 id=130 data-nosnippet>130</a> <span class="kw">if </span><span class="kw-2">*</span>b {
|
||||
<a href=#131 id=131 data-nosnippet>131</a> <span class="string">"TRUE"</span>.into()
|
||||
<a href=#132 id=132 data-nosnippet>132</a> } <span class="kw">else </span>{
|
||||
<a href=#133 id=133 data-nosnippet>133</a> <span class="string">"FALSE"</span>.into()
|
||||
<a href=#134 id=134 data-nosnippet>134</a> }
|
||||
<a href=#135 id=135 data-nosnippet>135</a> }
|
||||
<a href=#136 id=136 data-nosnippet>136</a> Value::Null => <span class="string">"NULL"</span>.into(),
|
||||
<a href=#137 id=137 data-nosnippet>137</a> <span class="kw">_ </span>=> <span class="kw">return </span><span class="prelude-val">Err</span>(GraphError::Other(<span class="string">"Unsupported JSON value type"</span>.into())),
|
||||
<a href=#138 id=138 data-nosnippet>138</a> };
|
||||
<a href=#139 id=139 data-nosnippet>139</a> values.push(sql_val);
|
||||
<a href=#140 id=140 data-nosnippet>140</a> }
|
||||
<a href=#141 id=141 data-nosnippet>141</a> <span class="kw">let </span>query = <span class="macro">format!</span>(
|
||||
<a href=#142 id=142 data-nosnippet>142</a> <span class="string">"INSERT INTO {} ({}) VALUES ({})"</span>,
|
||||
<a href=#143 id=143 data-nosnippet>143</a> table,
|
||||
<a href=#144 id=144 data-nosnippet>144</a> columns.join(<span class="string">", "</span>),
|
||||
<a href=#145 id=145 data-nosnippet>145</a> values.join(<span class="string">", "</span>)
|
||||
<a href=#146 id=146 data-nosnippet>146</a> );
|
||||
<a href=#147 id=147 data-nosnippet>147</a> <span class="self">self</span>.run_cmd(<span class="kw-2">&</span>[<span class="string">"sql"</span>, <span class="string">"-q"</span>, <span class="kw-2">&</span>query])<span class="question-mark">?</span>;
|
||||
<a href=#148 id=148 data-nosnippet>148</a> <span class="prelude-val">Ok</span>(())
|
||||
<a href=#149 id=149 data-nosnippet>149</a> }
|
||||
<a href=#150 id=150 data-nosnippet>150</a>}
|
||||
<a href=#151 id=151 data-nosnippet>151</a>
|
||||
<a href=#152 id=152 data-nosnippet>152</a><span class="attr">#[cfg(test)]
|
||||
<a href=#153 id=153 data-nosnippet>153</a></span><span class="kw">mod </span>tests {
|
||||
<a href=#154 id=154 data-nosnippet>154</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
|
||||
<a href=#155 id=155 data-nosnippet>155</a> <span class="kw">use </span>tempfile::TempDir;
|
||||
<a href=#156 id=156 data-nosnippet>156</a>
|
||||
<a href=#157 id=157 data-nosnippet>157</a> <span class="attr">#[test]
|
||||
<a href=#158 id=158 data-nosnippet>158</a> </span><span class="kw">fn </span>test_init_create_table_and_commit() {
|
||||
<a href=#159 id=159 data-nosnippet>159</a> <span class="kw">let </span>dir = TempDir::new().unwrap();
|
||||
<a href=#160 id=160 data-nosnippet>160</a> <span class="comment">// Initialise a Dolt repository in a temporary directory.
|
||||
<a href=#161 id=161 data-nosnippet>161</a> </span><span class="kw">let </span>graph = DoltGraph::init(dir.path()).expect(<span class="string">"init failed"</span>);
|
||||
<a href=#162 id=162 data-nosnippet>162</a> <span class="comment">// Create a simple `nodes` table.
|
||||
<a href=#163 id=163 data-nosnippet>163</a> </span>graph
|
||||
<a href=#164 id=164 data-nosnippet>164</a> .create_table(<span class="string">"nodes"</span>, <span class="string">"id INT PRIMARY KEY, name TEXT"</span>)
|
||||
<a href=#165 id=165 data-nosnippet>165</a> .expect(<span class="string">"create table failed"</span>);
|
||||
<a href=#166 id=166 data-nosnippet>166</a> }
|
||||
<a href=#167 id=167 data-nosnippet>167</a>}</code></pre></div></section></main></body></html>
|
||||
235
target/doc/src/chrs_mail/lib.rs.html
Normal file
235
target/doc/src/chrs_mail/lib.rs.html
Normal file
@@ -0,0 +1,235 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `chrs-mail/src/lib.rs`."><title>lib.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="chrs_mail" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../../static.files/storage-82c7156e.js"></script><script defer src="../../static.files/src-script-63605ae7.js"></script><script defer src="../../src-files.js"></script><script defer src="../../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer"></div><main><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1><div class="sub-heading">chrs_mail/</div>lib.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="doccomment">//! chrs-mail library implementation
|
||||
<a href=#2 id=2 data-nosnippet>2</a>
|
||||
<a href=#3 id=3 data-nosnippet>3</a></span><span class="kw">use </span>std::path::Path;
|
||||
<a href=#4 id=4 data-nosnippet>4</a><span class="kw">use </span>chrono::{DateTime, Utc};
|
||||
<a href=#5 id=5 data-nosnippet>5</a><span class="kw">use </span>rusqlite::{params, Connection};
|
||||
<a href=#6 id=6 data-nosnippet>6</a><span class="kw">use </span>serde::{Deserialize, Serialize};
|
||||
<a href=#7 id=7 data-nosnippet>7</a><span class="kw">use </span>serde_json::Value <span class="kw">as </span>JsonValue;
|
||||
<a href=#8 id=8 data-nosnippet>8</a><span class="kw">use </span>thiserror::Error;
|
||||
<a href=#9 id=9 data-nosnippet>9</a><span class="kw">use </span>uuid::Uuid;
|
||||
<a href=#10 id=10 data-nosnippet>10</a>
|
||||
<a href=#11 id=11 data-nosnippet>11</a><span class="doccomment">/// Represents a mail message stored in the mailbox.
|
||||
<a href=#12 id=12 data-nosnippet>12</a>///
|
||||
<a href=#13 id=13 data-nosnippet>13</a>/// # Definition
|
||||
<a href=#14 id=14 data-nosnippet>14</a>/// `Message` is a data structure that models a single mail exchange between two peers.
|
||||
<a href=#15 id=15 data-nosnippet>15</a>/// It contains a unique identifier, sender and recipient identifiers, a topic string, a JSON payload,
|
||||
<a href=#16 id=16 data-nosnippet>16</a>/// and timestamps for when the message was sent and optionally when it was read.
|
||||
<a href=#17 id=17 data-nosnippet>17</a>///
|
||||
<a href=#18 id=18 data-nosnippet>18</a>/// # Implementation Details
|
||||
<a href=#19 id=19 data-nosnippet>19</a>/// - `id` is a **Uuid** generated by the caller to guarantee global uniqueness.
|
||||
<a href=#20 id=20 data-nosnippet>20</a>/// - `payload` uses `serde_json::Value` so arbitrary JSON can be attached to the message.
|
||||
<a href=#21 id=21 data-nosnippet>21</a>/// - `sent_at` and `read_at` are stored as `chrono::DateTime<Utc>` to provide timezone‑agnostic timestamps.
|
||||
<a href=#22 id=22 data-nosnippet>22</a>///
|
||||
<a href=#23 id=23 data-nosnippet>23</a>/// # Rationale
|
||||
<a href=#24 id=24 data-nosnippet>24</a>/// This struct provides a lightweight, serialisable representation of a message that can be persisted
|
||||
<a href=#25 id=25 data-nosnippet>25</a>/// in the SQLite‑backed mailbox (see `Mailbox`). Keeping the payload as JSON allows different subsystems
|
||||
<a href=#26 id=26 data-nosnippet>26</a>/// of the CHORUS platform to embed domain‑specific data without requiring a rigid schema.
|
||||
<a href=#27 id=27 data-nosnippet>27</a></span><span class="attr">#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
<a href=#28 id=28 data-nosnippet>28</a></span><span class="kw">pub struct </span>Message {
|
||||
<a href=#29 id=29 data-nosnippet>29</a> <span class="doccomment">/// Globally unique identifier for the message.
|
||||
<a href=#30 id=30 data-nosnippet>30</a> </span><span class="kw">pub </span>id: Uuid,
|
||||
<a href=#31 id=31 data-nosnippet>31</a> <span class="doccomment">/// Identifier of the sending peer.
|
||||
<a href=#32 id=32 data-nosnippet>32</a> </span><span class="kw">pub </span>from_peer: String,
|
||||
<a href=#33 id=33 data-nosnippet>33</a> <span class="doccomment">/// Identifier of the receiving peer.
|
||||
<a href=#34 id=34 data-nosnippet>34</a> </span><span class="kw">pub </span>to_peer: String,
|
||||
<a href=#35 id=35 data-nosnippet>35</a> <span class="doccomment">/// Topic or channel of the message; used for routing/filters.
|
||||
<a href=#36 id=36 data-nosnippet>36</a> </span><span class="kw">pub </span>topic: String,
|
||||
<a href=#37 id=37 data-nosnippet>37</a> <span class="doccomment">/// Arbitrary JSON payload containing the message body.
|
||||
<a href=#38 id=38 data-nosnippet>38</a> </span><span class="kw">pub </span>payload: JsonValue,
|
||||
<a href=#39 id=39 data-nosnippet>39</a> <span class="doccomment">/// Timestamp (UTC) when the message was sent.
|
||||
<a href=#40 id=40 data-nosnippet>40</a> </span><span class="kw">pub </span>sent_at: DateTime<Utc>,
|
||||
<a href=#41 id=41 data-nosnippet>41</a> <span class="doccomment">/// Optional timestamp (UTC) when the recipient read the message.
|
||||
<a href=#42 id=42 data-nosnippet>42</a> </span><span class="kw">pub </span>read_at: <span class="prelude-ty">Option</span><DateTime<Utc>>,
|
||||
<a href=#43 id=43 data-nosnippet>43</a>}
|
||||
<a href=#44 id=44 data-nosnippet>44</a>
|
||||
<a href=#45 id=45 data-nosnippet>45</a><span class="doccomment">/// Errors that can occur while using the `Mailbox`.
|
||||
<a href=#46 id=46 data-nosnippet>46</a>///
|
||||
<a href=#47 id=47 data-nosnippet>47</a>/// Each variant wraps an underlying error type from a dependency, allowing callers to
|
||||
<a href=#48 id=48 data-nosnippet>48</a>/// react appropriately (e.g., retry on SQLite errors, surface serialization problems, etc.).
|
||||
<a href=#49 id=49 data-nosnippet>49</a></span><span class="attr">#[derive(Debug, Error)]
|
||||
<a href=#50 id=50 data-nosnippet>50</a></span><span class="kw">pub enum </span>MailError {
|
||||
<a href=#51 id=51 data-nosnippet>51</a> <span class="doccomment">/// Propagates any `rusqlite::Error` encountered while interacting with the SQLite DB.
|
||||
<a href=#52 id=52 data-nosnippet>52</a> </span><span class="attr">#[error(<span class="string">"SQLite error: {0}"</span>)]
|
||||
<a href=#53 id=53 data-nosnippet>53</a> </span>Sqlite(<span class="attr">#[from] </span>rusqlite::Error),
|
||||
<a href=#54 id=54 data-nosnippet>54</a> <span class="doccomment">/// Propagates JSON (de)serialization errors from `serde_json`.
|
||||
<a href=#55 id=55 data-nosnippet>55</a> </span><span class="attr">#[error(<span class="string">"JSON serialization error: {0}"</span>)]
|
||||
<a href=#56 id=56 data-nosnippet>56</a> </span>Json(<span class="attr">#[from] </span>serde_json::Error),
|
||||
<a href=#57 id=57 data-nosnippet>57</a> <span class="doccomment">/// Propagates UUID parsing errors.
|
||||
<a href=#58 id=58 data-nosnippet>58</a> </span><span class="attr">#[error(<span class="string">"UUID parsing error: {0}"</span>)]
|
||||
<a href=#59 id=59 data-nosnippet>59</a> </span>Uuid(<span class="attr">#[from] </span>uuid::Error),
|
||||
<a href=#60 id=60 data-nosnippet>60</a> <span class="doccomment">/// Propagates chrono parsing errors, primarily when deserialising timestamps from string.
|
||||
<a href=#61 id=61 data-nosnippet>61</a> </span><span class="attr">#[error(<span class="string">"Chrono parsing error: {0}"</span>)]
|
||||
<a href=#62 id=62 data-nosnippet>62</a> </span>ChronoParse(<span class="attr">#[from] </span>chrono::ParseError),
|
||||
<a href=#63 id=63 data-nosnippet>63</a>}
|
||||
<a href=#64 id=64 data-nosnippet>64</a>
|
||||
<a href=#65 id=65 data-nosnippet>65</a><span class="doccomment">/// Wrapper around a SQLite connection providing mailbox‑style functionalities.
|
||||
<a href=#66 id=66 data-nosnippet>66</a>///
|
||||
<a href=#67 id=67 data-nosnippet>67</a>/// The `Mailbox` abstracts a SQLite database that stores `Message` records. It offers a minimal
|
||||
<a href=#68 id=68 data-nosnippet>68</a>/// API for opening/creating the DB, sending messages, receiving pending messages for a peer, and
|
||||
<a href=#69 id=69 data-nosnippet>69</a>/// marking messages as read.
|
||||
<a href=#70 id=70 data-nosnippet>70</a>///
|
||||
<a href=#71 id=71 data-nosnippet>71</a>/// # Architectural Rationale
|
||||
<a href=#72 id=72 data-nosnippet>72</a>/// Using SQLite (via `rusqlite`) provides a zero‑configuration, file‑based persistence layer that is
|
||||
<a href=#73 id=73 data-nosnippet>73</a>/// portable across the various environments where CHORUS components may run. The wrapper isolates the
|
||||
<a href=#74 id=74 data-nosnippet>74</a>/// rest of the codebase from raw SQL handling, ensuring a single place for schema evolution and error
|
||||
<a href=#75 id=75 data-nosnippet>75</a>/// mapping.
|
||||
<a href=#76 id=76 data-nosnippet>76</a></span><span class="kw">pub struct </span>Mailbox {
|
||||
<a href=#77 id=77 data-nosnippet>77</a> conn: Connection,
|
||||
<a href=#78 id=78 data-nosnippet>78</a>}
|
||||
<a href=#79 id=79 data-nosnippet>79</a>
|
||||
<a href=#80 id=80 data-nosnippet>80</a><span class="kw">impl </span>Mailbox {
|
||||
<a href=#81 id=81 data-nosnippet>81</a> <span class="doccomment">/// Open (or create) a mailbox database at `path`.
|
||||
<a href=#82 id=82 data-nosnippet>82</a> ///
|
||||
<a href=#83 id=83 data-nosnippet>83</a> /// The function creates the SQLite file if it does not exist, enables WAL mode for better
|
||||
<a href=#84 id=84 data-nosnippet>84</a> /// concurrency, and ensures the `messages` table is present.
|
||||
<a href=#85 id=85 data-nosnippet>85</a> </span><span class="kw">pub fn </span>open<P: AsRef<Path>>(path: P) -> <span class="prelude-ty">Result</span><<span class="self">Self</span>, MailError> {
|
||||
<a href=#86 id=86 data-nosnippet>86</a> <span class="kw">let </span>conn = Connection::open(path)<span class="question-mark">?</span>;
|
||||
<a href=#87 id=87 data-nosnippet>87</a> <span class="comment">// Enable WAL mode for improved concurrency and durability.
|
||||
<a href=#88 id=88 data-nosnippet>88</a> </span>conn.pragma_update(<span class="prelude-val">None</span>, <span class="string">"journal_mode"</span>, <span class="kw-2">&</span><span class="string">"WAL"</span>)<span class="question-mark">?</span>;
|
||||
<a href=#89 id=89 data-nosnippet>89</a> <span class="comment">// Create the `messages` table if it does not already exist.
|
||||
<a href=#90 id=90 data-nosnippet>90</a> </span>conn.execute(
|
||||
<a href=#91 id=91 data-nosnippet>91</a> <span class="string">"CREATE TABLE IF NOT EXISTS messages (
|
||||
<a href=#92 id=92 data-nosnippet>92</a> id TEXT PRIMARY KEY,
|
||||
<a href=#93 id=93 data-nosnippet>93</a> from_peer TEXT NOT NULL,
|
||||
<a href=#94 id=94 data-nosnippet>94</a> to_peer TEXT NOT NULL,
|
||||
<a href=#95 id=95 data-nosnippet>95</a> topic TEXT NOT NULL,
|
||||
<a href=#96 id=96 data-nosnippet>96</a> payload TEXT NOT NULL,
|
||||
<a href=#97 id=97 data-nosnippet>97</a> sent_at TEXT NOT NULL,
|
||||
<a href=#98 id=98 data-nosnippet>98</a> read_at TEXT
|
||||
<a href=#99 id=99 data-nosnippet>99</a> )"</span>,
|
||||
<a href=#100 id=100 data-nosnippet>100</a> [],
|
||||
<a href=#101 id=101 data-nosnippet>101</a> )<span class="question-mark">?</span>;
|
||||
<a href=#102 id=102 data-nosnippet>102</a> <span class="prelude-val">Ok</span>(<span class="self">Self </span>{ conn })
|
||||
<a href=#103 id=103 data-nosnippet>103</a> }
|
||||
<a href=#104 id=104 data-nosnippet>104</a>
|
||||
<a href=#105 id=105 data-nosnippet>105</a> <span class="doccomment">/// Store a new message in the mailbox.
|
||||
<a href=#106 id=106 data-nosnippet>106</a> ///
|
||||
<a href=#107 id=107 data-nosnippet>107</a> /// The `payload` field is serialised to a JSON string before insertion. The `read_at` column is
|
||||
<a href=#108 id=108 data-nosnippet>108</a> /// initialised to `NULL` because the message has not yet been consumed.
|
||||
<a href=#109 id=109 data-nosnippet>109</a> </span><span class="kw">pub fn </span>send(<span class="kw-2">&</span><span class="self">self</span>, msg: <span class="kw-2">&</span>Message) -> <span class="prelude-ty">Result</span><(), MailError> {
|
||||
<a href=#110 id=110 data-nosnippet>110</a> <span class="kw">let </span>payload_str = serde_json::to_string(<span class="kw-2">&</span>msg.payload)<span class="question-mark">?</span>;
|
||||
<a href=#111 id=111 data-nosnippet>111</a> <span class="self">self</span>.conn.execute(
|
||||
<a href=#112 id=112 data-nosnippet>112</a> <span class="string">"INSERT INTO messages (id, from_peer, to_peer, topic, payload, sent_at, read_at)
|
||||
<a href=#113 id=113 data-nosnippet>113</a> VALUES (?1, ?2, ?3, ?4, ?5, ?6, NULL)"</span>,
|
||||
<a href=#114 id=114 data-nosnippet>114</a> <span class="macro">params!</span>[
|
||||
<a href=#115 id=115 data-nosnippet>115</a> msg.id.to_string(),
|
||||
<a href=#116 id=116 data-nosnippet>116</a> <span class="kw-2">&</span>msg.from_peer,
|
||||
<a href=#117 id=117 data-nosnippet>117</a> <span class="kw-2">&</span>msg.to_peer,
|
||||
<a href=#118 id=118 data-nosnippet>118</a> <span class="kw-2">&</span>msg.topic,
|
||||
<a href=#119 id=119 data-nosnippet>119</a> payload_str,
|
||||
<a href=#120 id=120 data-nosnippet>120</a> msg.sent_at.to_rfc3339(),
|
||||
<a href=#121 id=121 data-nosnippet>121</a> ],
|
||||
<a href=#122 id=122 data-nosnippet>122</a> )<span class="question-mark">?</span>;
|
||||
<a href=#123 id=123 data-nosnippet>123</a> <span class="prelude-val">Ok</span>(())
|
||||
<a href=#124 id=124 data-nosnippet>124</a> }
|
||||
<a href=#125 id=125 data-nosnippet>125</a>
|
||||
<a href=#126 id=126 data-nosnippet>126</a> <span class="doccomment">/// Retrieve all unread messages addressed to `peer_id`.
|
||||
<a href=#127 id=127 data-nosnippet>127</a> ///
|
||||
<a href=#128 id=128 data-nosnippet>128</a> /// The query filters on `to_peer` and `read_at IS NULL`. Returned rows are transformed back into
|
||||
<a href=#129 id=129 data-nosnippet>129</a> /// `Message` structs, parsing the UUID, JSON payload, and RFC3339 timestamps.
|
||||
<a href=#130 id=130 data-nosnippet>130</a> </span><span class="kw">pub fn </span>receive_pending(<span class="kw-2">&</span><span class="self">self</span>, peer_id: <span class="kw-2">&</span>str) -> <span class="prelude-ty">Result</span><Vec<Message>, MailError> {
|
||||
<a href=#131 id=131 data-nosnippet>131</a> <span class="kw">let </span><span class="kw-2">mut </span>stmt = <span class="self">self</span>.conn.prepare(
|
||||
<a href=#132 id=132 data-nosnippet>132</a> <span class="string">"SELECT id, from_peer, to_peer, topic, payload, sent_at, read_at
|
||||
<a href=#133 id=133 data-nosnippet>133</a> FROM messages
|
||||
<a href=#134 id=134 data-nosnippet>134</a> WHERE to_peer = ?1 AND read_at IS NULL"</span>,
|
||||
<a href=#135 id=135 data-nosnippet>135</a> )<span class="question-mark">?</span>;
|
||||
<a href=#136 id=136 data-nosnippet>136</a> <span class="kw">let </span>rows = stmt.query_map(<span class="macro">params!</span>[peer_id], |row| {
|
||||
<a href=#137 id=137 data-nosnippet>137</a> <span class="kw">let </span>id_str: String = row.get(<span class="number">0</span>)<span class="question-mark">?</span>;
|
||||
<a href=#138 id=138 data-nosnippet>138</a> <span class="kw">let </span>from_peer: String = row.get(<span class="number">1</span>)<span class="question-mark">?</span>;
|
||||
<a href=#139 id=139 data-nosnippet>139</a> <span class="kw">let </span>to_peer: String = row.get(<span class="number">2</span>)<span class="question-mark">?</span>;
|
||||
<a href=#140 id=140 data-nosnippet>140</a> <span class="kw">let </span>topic: String = row.get(<span class="number">3</span>)<span class="question-mark">?</span>;
|
||||
<a href=#141 id=141 data-nosnippet>141</a> <span class="kw">let </span>payload_str: String = row.get(<span class="number">4</span>)<span class="question-mark">?</span>;
|
||||
<a href=#142 id=142 data-nosnippet>142</a> <span class="kw">let </span>sent_at_str: String = row.get(<span class="number">5</span>)<span class="question-mark">?</span>;
|
||||
<a href=#143 id=143 data-nosnippet>143</a> <span class="kw">let </span>read_at_opt: <span class="prelude-ty">Option</span><String> = row.get(<span class="number">6</span>)<span class="question-mark">?</span>;
|
||||
<a href=#144 id=144 data-nosnippet>144</a>
|
||||
<a href=#145 id=145 data-nosnippet>145</a> <span class="comment">// Parse Uuid
|
||||
<a href=#146 id=146 data-nosnippet>146</a> </span><span class="kw">let </span>id = Uuid::parse_str(<span class="kw-2">&</span>id_str)
|
||||
<a href=#147 id=147 data-nosnippet>147</a> .map_err(|e| rusqlite::Error::FromSqlConversionFailure(<span class="number">0</span>, rusqlite::types::Type::Text, Box::new(e)))<span class="question-mark">?</span>;
|
||||
<a href=#148 id=148 data-nosnippet>148</a> <span class="comment">// Parse JSON payload
|
||||
<a href=#149 id=149 data-nosnippet>149</a> </span><span class="kw">let </span>payload: JsonValue = serde_json::from_str(<span class="kw-2">&</span>payload_str)
|
||||
<a href=#150 id=150 data-nosnippet>150</a> .map_err(|e| rusqlite::Error::FromSqlConversionFailure(<span class="number">4</span>, rusqlite::types::Type::Text, Box::new(e)))<span class="question-mark">?</span>;
|
||||
<a href=#151 id=151 data-nosnippet>151</a> <span class="comment">// Parse timestamps
|
||||
<a href=#152 id=152 data-nosnippet>152</a> </span><span class="kw">let </span>sent_at = DateTime::parse_from_rfc3339(<span class="kw-2">&</span>sent_at_str)
|
||||
<a href=#153 id=153 data-nosnippet>153</a> .map_err(|e| rusqlite::Error::FromSqlConversionFailure(<span class="number">5</span>, rusqlite::types::Type::Text, Box::new(e)))<span class="question-mark">?
|
||||
<a href=#154 id=154 data-nosnippet>154</a> </span>.with_timezone(<span class="kw-2">&</span>Utc);
|
||||
<a href=#155 id=155 data-nosnippet>155</a> <span class="kw">let </span>read_at = <span class="kw">match </span>read_at_opt {
|
||||
<a href=#156 id=156 data-nosnippet>156</a> <span class="prelude-val">Some</span>(s) => <span class="prelude-val">Some</span>(
|
||||
<a href=#157 id=157 data-nosnippet>157</a> DateTime::parse_from_rfc3339(<span class="kw-2">&</span>s)
|
||||
<a href=#158 id=158 data-nosnippet>158</a> .map_err(|e| rusqlite::Error::FromSqlConversionFailure(<span class="number">6</span>, rusqlite::types::Type::Text, Box::new(e)))<span class="question-mark">?
|
||||
<a href=#159 id=159 data-nosnippet>159</a> </span>.with_timezone(<span class="kw-2">&</span>Utc),
|
||||
<a href=#160 id=160 data-nosnippet>160</a> ),
|
||||
<a href=#161 id=161 data-nosnippet>161</a> <span class="prelude-val">None </span>=> <span class="prelude-val">None</span>,
|
||||
<a href=#162 id=162 data-nosnippet>162</a> };
|
||||
<a href=#163 id=163 data-nosnippet>163</a>
|
||||
<a href=#164 id=164 data-nosnippet>164</a> <span class="prelude-val">Ok</span>(Message {
|
||||
<a href=#165 id=165 data-nosnippet>165</a> id,
|
||||
<a href=#166 id=166 data-nosnippet>166</a> from_peer,
|
||||
<a href=#167 id=167 data-nosnippet>167</a> to_peer,
|
||||
<a href=#168 id=168 data-nosnippet>168</a> topic,
|
||||
<a href=#169 id=169 data-nosnippet>169</a> payload,
|
||||
<a href=#170 id=170 data-nosnippet>170</a> sent_at,
|
||||
<a href=#171 id=171 data-nosnippet>171</a> read_at,
|
||||
<a href=#172 id=172 data-nosnippet>172</a> })
|
||||
<a href=#173 id=173 data-nosnippet>173</a> })<span class="question-mark">?</span>;
|
||||
<a href=#174 id=174 data-nosnippet>174</a>
|
||||
<a href=#175 id=175 data-nosnippet>175</a> <span class="kw">let </span><span class="kw-2">mut </span>msgs = Vec::new();
|
||||
<a href=#176 id=176 data-nosnippet>176</a> <span class="kw">for </span>msg_res <span class="kw">in </span>rows {
|
||||
<a href=#177 id=177 data-nosnippet>177</a> msgs.push(msg_res<span class="question-mark">?</span>);
|
||||
<a href=#178 id=178 data-nosnippet>178</a> }
|
||||
<a href=#179 id=179 data-nosnippet>179</a> <span class="prelude-val">Ok</span>(msgs)
|
||||
<a href=#180 id=180 data-nosnippet>180</a> }
|
||||
<a href=#181 id=181 data-nosnippet>181</a>
|
||||
<a href=#182 id=182 data-nosnippet>182</a> <span class="doccomment">/// Mark a message as read by setting its `read_at` timestamp.
|
||||
<a href=#183 id=183 data-nosnippet>183</a> ///
|
||||
<a href=#184 id=184 data-nosnippet>184</a> /// The current UTC time is stored in the `read_at` column for the row with the matching `id`.
|
||||
<a href=#185 id=185 data-nosnippet>185</a> </span><span class="kw">pub fn </span>mark_read(<span class="kw-2">&</span><span class="self">self</span>, msg_id: Uuid) -> <span class="prelude-ty">Result</span><(), MailError> {
|
||||
<a href=#186 id=186 data-nosnippet>186</a> <span class="kw">let </span>now = Utc::now().to_rfc3339();
|
||||
<a href=#187 id=187 data-nosnippet>187</a> <span class="self">self</span>.conn.execute(
|
||||
<a href=#188 id=188 data-nosnippet>188</a> <span class="string">"UPDATE messages SET read_at = ?1 WHERE id = ?2"</span>,
|
||||
<a href=#189 id=189 data-nosnippet>189</a> <span class="macro">params!</span>[now, msg_id.to_string()],
|
||||
<a href=#190 id=190 data-nosnippet>190</a> )<span class="question-mark">?</span>;
|
||||
<a href=#191 id=191 data-nosnippet>191</a> <span class="prelude-val">Ok</span>(())
|
||||
<a href=#192 id=192 data-nosnippet>192</a> }
|
||||
<a href=#193 id=193 data-nosnippet>193</a>}
|
||||
<a href=#194 id=194 data-nosnippet>194</a>
|
||||
<a href=#195 id=195 data-nosnippet>195</a><span class="attr">#[cfg(test)]
|
||||
<a href=#196 id=196 data-nosnippet>196</a></span><span class="kw">mod </span>tests {
|
||||
<a href=#197 id=197 data-nosnippet>197</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
|
||||
<a href=#198 id=198 data-nosnippet>198</a> <span class="kw">use </span>std::env;
|
||||
<a href=#199 id=199 data-nosnippet>199</a> <span class="kw">use </span>std::fs;
|
||||
<a href=#200 id=200 data-nosnippet>200</a>
|
||||
<a href=#201 id=201 data-nosnippet>201</a> <span class="kw">fn </span>temp_db_path() -> std::path::PathBuf {
|
||||
<a href=#202 id=202 data-nosnippet>202</a> <span class="kw">let </span><span class="kw-2">mut </span>dir = env::temp_dir();
|
||||
<a href=#203 id=203 data-nosnippet>203</a> dir.push(<span class="macro">format!</span>(<span class="string">"chrs_mail_test_{}.sqlite"</span>, Uuid::new_v4()));
|
||||
<a href=#204 id=204 data-nosnippet>204</a> dir
|
||||
<a href=#205 id=205 data-nosnippet>205</a> }
|
||||
<a href=#206 id=206 data-nosnippet>206</a>
|
||||
<a href=#207 id=207 data-nosnippet>207</a> <span class="attr">#[test]
|
||||
<a href=#208 id=208 data-nosnippet>208</a> </span><span class="kw">fn </span>roundtrip_send_and_receive() -> <span class="prelude-ty">Result</span><(), MailError> {
|
||||
<a href=#209 id=209 data-nosnippet>209</a> <span class="kw">let </span>db_path = temp_db_path();
|
||||
<a href=#210 id=210 data-nosnippet>210</a> <span class="kw">if </span>db_path.exists() {
|
||||
<a href=#211 id=211 data-nosnippet>211</a> fs::remove_file(<span class="kw-2">&</span>db_path).unwrap();
|
||||
<a href=#212 id=212 data-nosnippet>212</a> }
|
||||
<a href=#213 id=213 data-nosnippet>213</a> <span class="kw">let </span>mailbox = Mailbox::open(<span class="kw-2">&</span>db_path)<span class="question-mark">?</span>;
|
||||
<a href=#214 id=214 data-nosnippet>214</a> <span class="kw">let </span>msg = Message {
|
||||
<a href=#215 id=215 data-nosnippet>215</a> id: Uuid::new_v4(),
|
||||
<a href=#216 id=216 data-nosnippet>216</a> from_peer: <span class="string">"alice"</span>.into(),
|
||||
<a href=#217 id=217 data-nosnippet>217</a> to_peer: <span class="string">"bob"</span>.into(),
|
||||
<a href=#218 id=218 data-nosnippet>218</a> topic: <span class="string">"greeting"</span>.into(),
|
||||
<a href=#219 id=219 data-nosnippet>219</a> payload: <span class="macro">serde_json::json!</span>({<span class="string">"text"</span>: <span class="string">"Hello"</span>}),
|
||||
<a href=#220 id=220 data-nosnippet>220</a> sent_at: Utc::now(),
|
||||
<a href=#221 id=221 data-nosnippet>221</a> read_at: <span class="prelude-val">None</span>,
|
||||
<a href=#222 id=222 data-nosnippet>222</a> };
|
||||
<a href=#223 id=223 data-nosnippet>223</a> mailbox.send(<span class="kw-2">&</span>msg)<span class="question-mark">?</span>;
|
||||
<a href=#224 id=224 data-nosnippet>224</a> <span class="kw">let </span>pending = mailbox.receive_pending(<span class="string">"bob"</span>)<span class="question-mark">?</span>;
|
||||
<a href=#225 id=225 data-nosnippet>225</a> <span class="macro">assert_eq!</span>(pending.len(), <span class="number">1</span>);
|
||||
<a href=#226 id=226 data-nosnippet>226</a> <span class="macro">assert_eq!</span>(pending[<span class="number">0</span>].id, msg.id);
|
||||
<a href=#227 id=227 data-nosnippet>227</a>
|
||||
<a href=#228 id=228 data-nosnippet>228</a> mailbox.mark_read(msg.id)<span class="question-mark">?</span>;
|
||||
<a href=#229 id=229 data-nosnippet>229</a> <span class="kw">let </span>pending2 = mailbox.receive_pending(<span class="string">"bob"</span>)<span class="question-mark">?</span>;
|
||||
<a href=#230 id=230 data-nosnippet>230</a> <span class="macro">assert!</span>(pending2.is_empty());
|
||||
<a href=#231 id=231 data-nosnippet>231</a>
|
||||
<a href=#232 id=232 data-nosnippet>232</a> fs::remove_file(db_path).unwrap();
|
||||
<a href=#233 id=233 data-nosnippet>233</a> <span class="prelude-val">Ok</span>(())
|
||||
<a href=#234 id=234 data-nosnippet>234</a> }
|
||||
<a href=#235 id=235 data-nosnippet>235</a>}</code></pre></div></section></main></body></html>
|
||||
128
target/doc/src/chrs_poc/main.rs.html
Normal file
128
target/doc/src/chrs_poc/main.rs.html
Normal file
@@ -0,0 +1,128 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `chrs-poc/src/main.rs`."><title>main.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="chrs_poc" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../../static.files/storage-82c7156e.js"></script><script defer src="../../static.files/src-script-63605ae7.js"></script><script defer src="../../src-files.js"></script><script defer src="../../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer"></div><main><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1><div class="sub-heading">chrs_poc/</div>main.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="doccomment">/// chrs-poc crate provides an end‑to‑end proof‑of‑concept demonstration of the CHORUS
|
||||
<a href=#2 id=2 data-nosnippet>2</a>/// system. It wires together the core components:
|
||||
<a href=#3 id=3 data-nosnippet>3</a>///
|
||||
<a href=#4 id=4 data-nosnippet>4</a>/// * `Mailbox` – message‑passing layer (`chrs_mail`).
|
||||
<a href=#5 id=5 data-nosnippet>5</a>/// * `DoltGraph` – persistent state graph (`chrs_graph`).
|
||||
<a href=#6 id=6 data-nosnippet>6</a>/// * `ProvenanceGraph` – provenance tracking (`chrs_bubble`).
|
||||
<a href=#7 id=7 data-nosnippet>7</a>/// * `SecretSentinel` – secret scrubbing (`chrs_shhh`).
|
||||
<a href=#8 id=8 data-nosnippet>8</a>/// * `CurationEngine` – decision record curation (`chrs_slurp`).
|
||||
<a href=#9 id=9 data-nosnippet>9</a>///
|
||||
<a href=#10 id=10 data-nosnippet>10</a>/// The flow mirrors a realistic task lifecycle: a client dispatches a task
|
||||
<a href=#11 id=11 data-nosnippet>11</a>/// message, an agent processes it, generates reasoning (with a deliberately
|
||||
<a href=#12 id=12 data-nosnippet>12</a>/// injected secret), the secret is scrubbed, a decision record is curated, and
|
||||
<a href=#13 id=13 data-nosnippet>13</a>/// provenance links are recorded. The final state is persisted in a Dolt
|
||||
<a href=#14 id=14 data-nosnippet>14</a>/// repository.
|
||||
<a href=#15 id=15 data-nosnippet>15</a>
|
||||
<a href=#16 id=16 data-nosnippet>16</a></span><span class="kw">use </span>chrs_bubble::{ProvenanceGraph, ProvenanceEdge};
|
||||
<a href=#17 id=17 data-nosnippet>17</a><span class="kw">use </span>chrs_graph::DoltGraph;
|
||||
<a href=#18 id=18 data-nosnippet>18</a><span class="kw">use </span>chrs_mail::{Mailbox, Message};
|
||||
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span>chrs_shhh::SecretSentinel;
|
||||
<a href=#20 id=20 data-nosnippet>20</a><span class="kw">use </span>chrs_slurp::{CurationEngine, DecisionRecord};
|
||||
<a href=#21 id=21 data-nosnippet>21</a><span class="kw">use </span>chrono::Utc;
|
||||
<a href=#22 id=22 data-nosnippet>22</a><span class="kw">use </span>std::fs;
|
||||
<a href=#23 id=23 data-nosnippet>23</a><span class="kw">use </span>std::path::Path;
|
||||
<a href=#24 id=24 data-nosnippet>24</a><span class="kw">use </span>uuid::Uuid;
|
||||
<a href=#25 id=25 data-nosnippet>25</a>
|
||||
<a href=#26 id=26 data-nosnippet>26</a><span class="doccomment">/// Entry point for the proof‑of‑concept binary.
|
||||
<a href=#27 id=27 data-nosnippet>27</a>///
|
||||
<a href=#28 id=28 data-nosnippet>28</a>/// The function performs the following high‑level steps, each documented inline:
|
||||
<a href=#29 id=29 data-nosnippet>29</a>/// 1. Sets up a temporary workspace.
|
||||
<a href=#30 id=30 data-nosnippet>30</a>/// 2. Initialises all required components.
|
||||
<a href=#31 id=31 data-nosnippet>31</a>/// 3. Simulates a client sending an audit task to an agent.
|
||||
<a href=#32 id=32 data-nosnippet>32</a>/// 4. Processes the task as the agent would, including secret scrubbing.
|
||||
<a href=#33 id=33 data-nosnippet>33</a>/// 5. Curates a `DecisionRecord` via the SLURP engine.
|
||||
<a href=#34 id=34 data-nosnippet>34</a>/// 6. Records provenance relationships in the BUBBLE graph.
|
||||
<a href=#35 id=35 data-nosnippet>35</a>/// 7. Prints a success banner and the path to the persisted Dolt state.
|
||||
<a href=#36 id=36 data-nosnippet>36</a>///
|
||||
<a href=#37 id=37 data-nosnippet>37</a>/// Errors from any component propagate via `?` and are reported as a boxed error.
|
||||
<a href=#38 id=38 data-nosnippet>38</a></span><span class="attr">#[tokio::main]
|
||||
<a href=#39 id=39 data-nosnippet>39</a></span><span class="kw">async fn </span>main() -> <span class="prelude-ty">Result</span><(), Box<<span class="kw">dyn </span>std::error::Error>> {
|
||||
<a href=#40 id=40 data-nosnippet>40</a> <span class="macro">println!</span>(<span class="string">"=== CHORUS End-to-End Proof of Concept ==="</span>);
|
||||
<a href=#41 id=41 data-nosnippet>41</a>
|
||||
<a href=#42 id=42 data-nosnippet>42</a> <span class="comment">// ---------------------------------------------------------------------
|
||||
<a href=#43 id=43 data-nosnippet>43</a> // 1. Setup paths
|
||||
<a href=#44 id=44 data-nosnippet>44</a> // ---------------------------------------------------------------------
|
||||
<a href=#45 id=45 data-nosnippet>45</a> </span><span class="kw">let </span>base_path = Path::new(<span class="string">"/tmp/chrs_poc"</span>);
|
||||
<a href=#46 id=46 data-nosnippet>46</a> <span class="kw">if </span>base_path.exists() {
|
||||
<a href=#47 id=47 data-nosnippet>47</a> fs::remove_dir_all(base_path)<span class="question-mark">?</span>;
|
||||
<a href=#48 id=48 data-nosnippet>48</a> }
|
||||
<a href=#49 id=49 data-nosnippet>49</a> fs::create_dir_all(base_path)<span class="question-mark">?</span>;
|
||||
<a href=#50 id=50 data-nosnippet>50</a>
|
||||
<a href=#51 id=51 data-nosnippet>51</a> <span class="kw">let </span>mail_path = base_path.join(<span class="string">"mail.sqlite"</span>);
|
||||
<a href=#52 id=52 data-nosnippet>52</a> <span class="kw">let </span>graph_path = base_path.join(<span class="string">"state_graph"</span>);
|
||||
<a href=#53 id=53 data-nosnippet>53</a> fs::create_dir_all(<span class="kw-2">&</span>graph_path)<span class="question-mark">?</span>;
|
||||
<a href=#54 id=54 data-nosnippet>54</a>
|
||||
<a href=#55 id=55 data-nosnippet>55</a> <span class="comment">// ---------------------------------------------------------------------
|
||||
<a href=#56 id=56 data-nosnippet>56</a> // 2. Initialise Components
|
||||
<a href=#57 id=57 data-nosnippet>57</a> // ---------------------------------------------------------------------
|
||||
<a href=#58 id=58 data-nosnippet>58</a> </span><span class="kw">let </span>mailbox = Mailbox::open(<span class="kw-2">&</span>mail_path)<span class="question-mark">?</span>;
|
||||
<a href=#59 id=59 data-nosnippet>59</a> <span class="kw">let </span>persistence = DoltGraph::init(<span class="kw-2">&</span>graph_path)<span class="question-mark">?</span>;
|
||||
<a href=#60 id=60 data-nosnippet>60</a> <span class="kw">let </span><span class="kw-2">mut </span>provenance = ProvenanceGraph::new(persistence);
|
||||
<a href=#61 id=61 data-nosnippet>61</a>
|
||||
<a href=#62 id=62 data-nosnippet>62</a> <span class="comment">// A separate graph handle is needed for the SLURP engine because the
|
||||
<a href=#63 id=63 data-nosnippet>63</a> // provenance graph consumes the original `DoltGraph`. In production we would
|
||||
<a href=#64 id=64 data-nosnippet>64</a> // share via `Arc<Mutex<>>`.
|
||||
<a href=#65 id=65 data-nosnippet>65</a> </span><span class="kw">let </span>slurp_persistence = DoltGraph::init(<span class="kw-2">&</span>graph_path)<span class="question-mark">?</span>;
|
||||
<a href=#66 id=66 data-nosnippet>66</a> <span class="kw">let </span>curator = CurationEngine::new(slurp_persistence);
|
||||
<a href=#67 id=67 data-nosnippet>67</a> <span class="kw">let </span>sentinel = SecretSentinel::new_default();
|
||||
<a href=#68 id=68 data-nosnippet>68</a>
|
||||
<a href=#69 id=69 data-nosnippet>69</a> <span class="macro">println!</span>(<span class="string">"[POC] Components initialized."</span>);
|
||||
<a href=#70 id=70 data-nosnippet>70</a>
|
||||
<a href=#71 id=71 data-nosnippet>71</a> <span class="comment">// ---------------------------------------------------------------------
|
||||
<a href=#72 id=72 data-nosnippet>72</a> // 3. Dispatch Task (simulate client sending message to Agent-A)
|
||||
<a href=#73 id=73 data-nosnippet>73</a> // ---------------------------------------------------------------------
|
||||
<a href=#74 id=74 data-nosnippet>74</a> </span><span class="kw">let </span>task_id = Uuid::new_v4();
|
||||
<a href=#75 id=75 data-nosnippet>75</a> <span class="kw">let </span>task_msg = Message {
|
||||
<a href=#76 id=76 data-nosnippet>76</a> id: task_id,
|
||||
<a href=#77 id=77 data-nosnippet>77</a> from_peer: <span class="string">"client"</span>.into(),
|
||||
<a href=#78 id=78 data-nosnippet>78</a> to_peer: <span class="string">"agent-a"</span>.into(),
|
||||
<a href=#79 id=79 data-nosnippet>79</a> topic: <span class="string">"audit_system"</span>.into(),
|
||||
<a href=#80 id=80 data-nosnippet>80</a> payload: <span class="macro">serde_json::json!</span>({<span class="string">"action"</span>: <span class="string">"audit"</span>, <span class="string">"target"</span>: <span class="string">"UCXL"</span>}),
|
||||
<a href=#81 id=81 data-nosnippet>81</a> sent_at: Utc::now(),
|
||||
<a href=#82 id=82 data-nosnippet>82</a> read_at: <span class="prelude-val">None</span>,
|
||||
<a href=#83 id=83 data-nosnippet>83</a> };
|
||||
<a href=#84 id=84 data-nosnippet>84</a> mailbox.send(<span class="kw-2">&</span>task_msg)<span class="question-mark">?</span>;
|
||||
<a href=#85 id=85 data-nosnippet>85</a> <span class="macro">println!</span>(<span class="string">"[POC] Task dispatched to Agent-A: {}"</span>, task_id);
|
||||
<a href=#86 id=86 data-nosnippet>86</a>
|
||||
<a href=#87 id=87 data-nosnippet>87</a> <span class="comment">// ---------------------------------------------------------------------
|
||||
<a href=#88 id=88 data-nosnippet>88</a> // 4. Process Task (Agent-A logic)
|
||||
<a href=#89 id=89 data-nosnippet>89</a> // ---------------------------------------------------------------------
|
||||
<a href=#90 id=90 data-nosnippet>90</a> </span><span class="kw">let </span>pending = mailbox.receive_pending(<span class="string">"agent-a"</span>)<span class="question-mark">?</span>;
|
||||
<a href=#91 id=91 data-nosnippet>91</a> <span class="kw">for </span>msg <span class="kw">in </span>pending {
|
||||
<a href=#92 id=92 data-nosnippet>92</a> <span class="macro">println!</span>(<span class="string">"[POC] Agent-A received task: {}"</span>, msg.topic);
|
||||
<a href=#93 id=93 data-nosnippet>93</a>
|
||||
<a href=#94 id=94 data-nosnippet>94</a> <span class="comment">// Simulated reasoning that accidentally contains a secret.
|
||||
<a href=#95 id=95 data-nosnippet>95</a> </span><span class="kw">let </span>raw_reasoning = <span class="string">"Audit complete. Verified UCXL address parsing. My secret key is sk-1234567890abcdef1234567890abcdef1234567890abcdef"</span>;
|
||||
<a href=#96 id=96 data-nosnippet>96</a>
|
||||
<a href=#97 id=97 data-nosnippet>97</a> <span class="comment">// 5. SHHH: Scrub secrets from the reasoning output.
|
||||
<a href=#98 id=98 data-nosnippet>98</a> </span><span class="kw">let </span>clean_reasoning = sentinel.scrub_text(raw_reasoning);
|
||||
<a href=#99 id=99 data-nosnippet>99</a> <span class="macro">println!</span>(<span class="string">"[POC] SHHH scrubbed reasoning: {}"</span>, clean_reasoning);
|
||||
<a href=#100 id=100 data-nosnippet>100</a>
|
||||
<a href=#101 id=101 data-nosnippet>101</a> <span class="comment">// 6. SLURP: Create and curate a DecisionRecord.
|
||||
<a href=#102 id=102 data-nosnippet>102</a> </span><span class="kw">let </span>dr = DecisionRecord {
|
||||
<a href=#103 id=103 data-nosnippet>103</a> id: Uuid::new_v4(),
|
||||
<a href=#104 id=104 data-nosnippet>104</a> author: <span class="string">"agent-a"</span>.into(),
|
||||
<a href=#105 id=105 data-nosnippet>105</a> reasoning: clean_reasoning,
|
||||
<a href=#106 id=106 data-nosnippet>106</a> citations: <span class="macro">vec!</span>[<span class="string">"ucxl://system:watcher@local:filesystem/#/UCXL/src/lib.rs"</span>.into()],
|
||||
<a href=#107 id=107 data-nosnippet>107</a> timestamp: Utc::now(),
|
||||
<a href=#108 id=108 data-nosnippet>108</a> };
|
||||
<a href=#109 id=109 data-nosnippet>109</a> curator.curate_decision(dr.clone())<span class="question-mark">?</span>;
|
||||
<a href=#110 id=110 data-nosnippet>110</a>
|
||||
<a href=#111 id=111 data-nosnippet>111</a> <span class="comment">// 7. BUBBLE: Record provenance relationships.
|
||||
<a href=#112 id=112 data-nosnippet>112</a> </span>provenance.record_node(task_id, <span class="string">"ucxl://client:user@poc:task/#/audit_request"</span>)<span class="question-mark">?</span>;
|
||||
<a href=#113 id=113 data-nosnippet>113</a> provenance.record_node(dr.id, <span class="string">"ucxl://agent-a:worker@poc:task/#/audit_result"</span>)<span class="question-mark">?</span>;
|
||||
<a href=#114 id=114 data-nosnippet>114</a> provenance.record_link(dr.id, task_id, ProvenanceEdge::DerivedFrom)<span class="question-mark">?</span>;
|
||||
<a href=#115 id=115 data-nosnippet>115</a>
|
||||
<a href=#116 id=116 data-nosnippet>116</a> <span class="macro">println!</span>(<span class="string">"[POC] Provenance recorded: DR {} -> Task {}"</span>, dr.id, task_id);
|
||||
<a href=#117 id=117 data-nosnippet>117</a>
|
||||
<a href=#118 id=118 data-nosnippet>118</a> mailbox.mark_read(msg.id)<span class="question-mark">?</span>;
|
||||
<a href=#119 id=119 data-nosnippet>119</a> }
|
||||
<a href=#120 id=120 data-nosnippet>120</a>
|
||||
<a href=#121 id=121 data-nosnippet>121</a> <span class="comment">// ---------------------------------------------------------------------
|
||||
<a href=#122 id=122 data-nosnippet>122</a> // 8. Final output
|
||||
<a href=#123 id=123 data-nosnippet>123</a> // ---------------------------------------------------------------------
|
||||
<a href=#124 id=124 data-nosnippet>124</a> </span><span class="macro">println!</span>(<span class="string">"\n=== POC SUCCESSFUL ==="</span>);
|
||||
<a href=#125 id=125 data-nosnippet>125</a> <span class="macro">println!</span>(<span class="string">"Final State is persisted in Dolt at: {:?}"</span>, graph_path);
|
||||
<a href=#126 id=126 data-nosnippet>126</a>
|
||||
<a href=#127 id=127 data-nosnippet>127</a> <span class="prelude-val">Ok</span>(())
|
||||
<a href=#128 id=128 data-nosnippet>128</a>}</code></pre></div></section></main></body></html>
|
||||
138
target/doc/src/chrs_shhh/lib.rs.html
Normal file
138
target/doc/src/chrs_shhh/lib.rs.html
Normal file
@@ -0,0 +1,138 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `chrs-shhh/src/lib.rs`."><title>lib.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="chrs_shhh" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../../static.files/storage-82c7156e.js"></script><script defer src="../../static.files/src-script-63605ae7.js"></script><script defer src="../../src-files.js"></script><script defer src="../../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer"></div><main><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1><div class="sub-heading">chrs_shhh/</div>lib.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="kw">use </span>lazy_static::lazy_static;
|
||||
<a href=#2 id=2 data-nosnippet>2</a><span class="doccomment">/// # chrs-shhh
|
||||
<a href=#3 id=3 data-nosnippet>3</a>///
|
||||
<a href=#4 id=4 data-nosnippet>4</a>/// This crate provides utilities for redacting sensitive information from text.
|
||||
<a href=#5 id=5 data-nosnippet>5</a>/// It defines a set of **redaction rules** that match secret patterns (like API keys)
|
||||
<a href=#6 id=6 data-nosnippet>6</a>/// and replace them with a placeholder. The crate is deliberately lightweight – it
|
||||
<a href=#7 id=7 data-nosnippet>7</a>/// only depends on `regex` and `lazy_static` – and can be embedded in any larger
|
||||
<a href=#8 id=8 data-nosnippet>8</a>/// application that needs to scrub logs or user‑provided data before storage or
|
||||
<a href=#9 id=9 data-nosnippet>9</a>/// transmission.
|
||||
<a href=#10 id=10 data-nosnippet>10</a></span><span class="kw">use </span>regex::Regex;
|
||||
<a href=#11 id=11 data-nosnippet>11</a>
|
||||
<a href=#12 id=12 data-nosnippet>12</a><span class="doccomment">/// Represents a single rule used to redact a secret.
|
||||
<a href=#13 id=13 data-nosnippet>13</a>///
|
||||
<a href=#14 id=14 data-nosnippet>14</a>/// * **WHAT** – The name of the rule (e.g. "OpenAI API Key"), the compiled
|
||||
<a href=#15 id=15 data-nosnippet>15</a>/// regular‑expression pattern that matches the secret, and the replacement string
|
||||
<a href=#16 id=16 data-nosnippet>16</a>/// that will be inserted.
|
||||
<a href=#17 id=17 data-nosnippet>17</a>/// * **HOW** – The `pattern` is a `Regex` that is applied to an input string. When a
|
||||
<a href=#18 id=18 data-nosnippet>18</a>/// match is found the `replacement` is inserted using `replace_all`.
|
||||
<a href=#19 id=19 data-nosnippet>19</a>/// * **WHY** – Decoupling the rule definition from the redaction logic makes the
|
||||
<a href=#20 id=20 data-nosnippet>20</a>/// sanitizer extensible; new patterns can be added without changing the core
|
||||
<a href=#21 id=21 data-nosnippet>21</a>/// implementation.
|
||||
<a href=#22 id=22 data-nosnippet>22</a></span><span class="kw">pub struct </span>RedactionRule {
|
||||
<a href=#23 id=23 data-nosnippet>23</a> <span class="doccomment">/// Human‑readable name for the rule.
|
||||
<a href=#24 id=24 data-nosnippet>24</a> </span><span class="kw">pub </span>name: String,
|
||||
<a href=#25 id=25 data-nosnippet>25</a> <span class="doccomment">/// Compiled regular expression that matches the secret.
|
||||
<a href=#26 id=26 data-nosnippet>26</a> </span><span class="kw">pub </span>pattern: Regex,
|
||||
<a href=#27 id=27 data-nosnippet>27</a> <span class="doccomment">/// Text that will replace the matched secret.
|
||||
<a href=#28 id=28 data-nosnippet>28</a> </span><span class="kw">pub </span>replacement: String,
|
||||
<a href=#29 id=29 data-nosnippet>29</a>}
|
||||
<a href=#30 id=30 data-nosnippet>30</a>
|
||||
<a href=#31 id=31 data-nosnippet>31</a><span class="doccomment">/// The main entry point for secret detection and redaction.
|
||||
<a href=#32 id=32 data-nosnippet>32</a>///
|
||||
<a href=#33 id=33 data-nosnippet>33</a>/// * **WHAT** – Holds a collection of `RedactionRule`s.
|
||||
<a href=#34 id=34 data-nosnippet>34</a>/// * **HOW** – Provides methods to scrub a string (`scrub_text`) and to simply
|
||||
<a href=#35 id=35 data-nosnippet>35</a>/// check whether any secret is present (`contains_secrets`).
|
||||
<a href=#36 id=36 data-nosnippet>36</a>/// * **WHY** – Centralising the rules in a struct enables reuse and makes testing
|
||||
<a href=#37 id=37 data-nosnippet>37</a>/// straightforward.
|
||||
<a href=#38 id=38 data-nosnippet>38</a></span><span class="kw">pub struct </span>SecretSentinel {
|
||||
<a href=#39 id=39 data-nosnippet>39</a> rules: Vec<RedactionRule>,
|
||||
<a href=#40 id=40 data-nosnippet>40</a>}
|
||||
<a href=#41 id=41 data-nosnippet>41</a>
|
||||
<a href=#42 id=42 data-nosnippet>42</a><span class="macro">lazy_static!</span> {
|
||||
<a href=#43 id=43 data-nosnippet>43</a> <span class="doccomment">/// Matches OpenAI API keys of the form `sk-<48 alphanumeric chars>`.
|
||||
<a href=#44 id=44 data-nosnippet>44</a> </span><span class="kw">static </span><span class="kw-2">ref </span>OPENAI_KEY: Regex = Regex::new(<span class="string">r"sk-[a-zA-Z0-9]{48}"</span>).unwrap();
|
||||
<a href=#45 id=45 data-nosnippet>45</a> <span class="doccomment">/// Matches AWS access keys that start with `AKIA` followed by 16 uppercase letters or digits.
|
||||
<a href=#46 id=46 data-nosnippet>46</a> </span><span class="kw">static </span><span class="kw-2">ref </span>AWS_KEY: Regex = Regex::new(<span class="string">r"AKIA[0-9A-Z]{16}"</span>).unwrap();
|
||||
<a href=#47 id=47 data-nosnippet>47</a> <span class="doccomment">/// Generic secret pattern that captures common keywords like password, secret, key or token.
|
||||
<a href=#48 id=48 data-nosnippet>48</a> /// The capture group (`$1`) is retained so that the surrounding identifier is preserved.
|
||||
<a href=#49 id=49 data-nosnippet>49</a> </span><span class="kw">static </span><span class="kw-2">ref </span>GENERIC_SECRET: Regex = Regex::new(<span class="string">r"(?i)(password|secret|key|token)\s*[:=]\s*[^\s]+"</span>).unwrap();
|
||||
<a href=#50 id=50 data-nosnippet>50</a>}
|
||||
<a href=#51 id=51 data-nosnippet>51</a>
|
||||
<a href=#52 id=52 data-nosnippet>52</a><span class="kw">impl </span>SecretSentinel {
|
||||
<a href=#53 id=53 data-nosnippet>53</a> <span class="doccomment">/// Constructs a `SecretSentinel` pre‑populated with a sensible default set of rules.
|
||||
<a href=#54 id=54 data-nosnippet>54</a> ///
|
||||
<a href=#55 id=55 data-nosnippet>55</a> /// * **WHAT** – Returns a sentinel containing three rules: OpenAI, AWS and a generic
|
||||
<a href=#56 id=56 data-nosnippet>56</a> /// secret matcher.
|
||||
<a href=#57 id=57 data-nosnippet>57</a> /// * **HOW** – Instantiates `RedactionRule`s using the lazily‑initialised regexes
|
||||
<a href=#58 id=58 data-nosnippet>58</a> /// above and stores them in the `rules` vector.
|
||||
<a href=#59 id=59 data-nosnippet>59</a> /// * **WHY** – Provides a ready‑to‑use configuration for typical development
|
||||
<a href=#60 id=60 data-nosnippet>60</a> /// environments while still allowing callers to create custom instances.
|
||||
<a href=#61 id=61 data-nosnippet>61</a> </span><span class="kw">pub fn </span>new_default() -> <span class="self">Self </span>{
|
||||
<a href=#62 id=62 data-nosnippet>62</a> <span class="kw">let </span>rules = <span class="macro">vec!</span>[
|
||||
<a href=#63 id=63 data-nosnippet>63</a> RedactionRule {
|
||||
<a href=#64 id=64 data-nosnippet>64</a> name: <span class="string">"OpenAI API Key"</span>.into(),
|
||||
<a href=#65 id=65 data-nosnippet>65</a> pattern: OPENAI_KEY.clone(),
|
||||
<a href=#66 id=66 data-nosnippet>66</a> replacement: <span class="string">"[REDACTED OPENAI KEY]"</span>.into(),
|
||||
<a href=#67 id=67 data-nosnippet>67</a> },
|
||||
<a href=#68 id=68 data-nosnippet>68</a> RedactionRule {
|
||||
<a href=#69 id=69 data-nosnippet>69</a> name: <span class="string">"AWS Access Key"</span>.into(),
|
||||
<a href=#70 id=70 data-nosnippet>70</a> pattern: AWS_KEY.clone(),
|
||||
<a href=#71 id=71 data-nosnippet>71</a> replacement: <span class="string">"[REDACTED AWS KEY]"</span>.into(),
|
||||
<a href=#72 id=72 data-nosnippet>72</a> },
|
||||
<a href=#73 id=73 data-nosnippet>73</a> RedactionRule {
|
||||
<a href=#74 id=74 data-nosnippet>74</a> name: <span class="string">"Generic Secret"</span>.into(),
|
||||
<a href=#75 id=75 data-nosnippet>75</a> pattern: GENERIC_SECRET.clone(),
|
||||
<a href=#76 id=76 data-nosnippet>76</a> <span class="comment">// $1 refers to the captured keyword (password, secret, …).
|
||||
<a href=#77 id=77 data-nosnippet>77</a> </span>replacement: <span class="string">"$1: [REDACTED]"</span>.into(),
|
||||
<a href=#78 id=78 data-nosnippet>78</a> },
|
||||
<a href=#79 id=79 data-nosnippet>79</a> ];
|
||||
<a href=#80 id=80 data-nosnippet>80</a> <span class="self">Self </span>{ rules }
|
||||
<a href=#81 id=81 data-nosnippet>81</a> }
|
||||
<a href=#82 id=82 data-nosnippet>82</a>
|
||||
<a href=#83 id=83 data-nosnippet>83</a> <span class="doccomment">/// Redacts all secrets found in `input` according to the configured rules.
|
||||
<a href=#84 id=84 data-nosnippet>84</a> ///
|
||||
<a href=#85 id=85 data-nosnippet>85</a> /// * **WHAT** – Returns a new `String` where each match has been replaced.
|
||||
<a href=#86 id=86 data-nosnippet>86</a> /// * **HOW** – Iterates over the rules and applies `replace_all` for each.
|
||||
<a href=#87 id=87 data-nosnippet>87</a> /// * **WHY** – Performing the replacements sequentially ensures that overlapping
|
||||
<a href=#88 id=88 data-nosnippet>88</a> /// patterns are handled deterministically.
|
||||
<a href=#89 id=89 data-nosnippet>89</a> </span><span class="kw">pub fn </span>scrub_text(<span class="kw-2">&</span><span class="self">self</span>, input: <span class="kw-2">&</span>str) -> String {
|
||||
<a href=#90 id=90 data-nosnippet>90</a> <span class="kw">let </span><span class="kw-2">mut </span>scrubbed = input.to_string();
|
||||
<a href=#91 id=91 data-nosnippet>91</a> <span class="kw">for </span>rule <span class="kw">in </span><span class="kw-2">&</span><span class="self">self</span>.rules {
|
||||
<a href=#92 id=92 data-nosnippet>92</a> scrubbed = rule
|
||||
<a href=#93 id=93 data-nosnippet>93</a> .pattern
|
||||
<a href=#94 id=94 data-nosnippet>94</a> .replace_all(<span class="kw-2">&</span>scrubbed, <span class="kw-2">&</span>rule.replacement)
|
||||
<a href=#95 id=95 data-nosnippet>95</a> .to_string();
|
||||
<a href=#96 id=96 data-nosnippet>96</a> }
|
||||
<a href=#97 id=97 data-nosnippet>97</a> scrubbed
|
||||
<a href=#98 id=98 data-nosnippet>98</a> }
|
||||
<a href=#99 id=99 data-nosnippet>99</a>
|
||||
<a href=#100 id=100 data-nosnippet>100</a> <span class="doccomment">/// Checks whether any of the configured rules match `input`.
|
||||
<a href=#101 id=101 data-nosnippet>101</a> ///
|
||||
<a href=#102 id=102 data-nosnippet>102</a> /// * **WHAT** – Returns `true` if at least one rule's pattern matches.
|
||||
<a href=#103 id=103 data-nosnippet>103</a> /// * **HOW** – Uses `Iter::any` over `self.rules` with `is_match`.
|
||||
<a href=#104 id=104 data-nosnippet>104</a> /// * **WHY** – A quick predicate useful for short‑circuiting logging or error
|
||||
<a href=#105 id=105 data-nosnippet>105</a> /// handling before performing the full redaction.
|
||||
<a href=#106 id=106 data-nosnippet>106</a> </span><span class="kw">pub fn </span>contains_secrets(<span class="kw-2">&</span><span class="self">self</span>, input: <span class="kw-2">&</span>str) -> bool {
|
||||
<a href=#107 id=107 data-nosnippet>107</a> <span class="self">self</span>.rules.iter().any(|rule| rule.pattern.is_match(input))
|
||||
<a href=#108 id=108 data-nosnippet>108</a> }
|
||||
<a href=#109 id=109 data-nosnippet>109</a>}
|
||||
<a href=#110 id=110 data-nosnippet>110</a>
|
||||
<a href=#111 id=111 data-nosnippet>111</a><span class="attr">#[cfg(test)]
|
||||
<a href=#112 id=112 data-nosnippet>112</a></span><span class="kw">mod </span>tests {
|
||||
<a href=#113 id=113 data-nosnippet>113</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
|
||||
<a href=#114 id=114 data-nosnippet>114</a>
|
||||
<a href=#115 id=115 data-nosnippet>115</a> <span class="attr">#[test]
|
||||
<a href=#116 id=116 data-nosnippet>116</a> </span><span class="kw">fn </span>test_scrub_openai_key() {
|
||||
<a href=#117 id=117 data-nosnippet>117</a> <span class="kw">let </span>sentinel = SecretSentinel::new_default();
|
||||
<a href=#118 id=118 data-nosnippet>118</a> <span class="kw">let </span>input = <span class="string">"My key is sk-1234567890abcdef1234567890abcdef1234567890abcdef"</span>;
|
||||
<a href=#119 id=119 data-nosnippet>119</a> <span class="kw">let </span>output = sentinel.scrub_text(input);
|
||||
<a href=#120 id=120 data-nosnippet>120</a> <span class="macro">assert!</span>(output.contains(<span class="string">"[REDACTED OPENAI KEY]"</span>));
|
||||
<a href=#121 id=121 data-nosnippet>121</a> <span class="macro">assert!</span>(!output.contains(<span class="string">"sk-1234567890"</span>));
|
||||
<a href=#122 id=122 data-nosnippet>122</a> }
|
||||
<a href=#123 id=123 data-nosnippet>123</a>
|
||||
<a href=#124 id=124 data-nosnippet>124</a> <span class="attr">#[test]
|
||||
<a href=#125 id=125 data-nosnippet>125</a> </span><span class="kw">fn </span>test_scrub_generic_password() {
|
||||
<a href=#126 id=126 data-nosnippet>126</a> <span class="kw">let </span>sentinel = SecretSentinel::new_default();
|
||||
<a href=#127 id=127 data-nosnippet>127</a> <span class="kw">let </span>input = <span class="string">"login with password: my-secret-password now"</span>;
|
||||
<a href=#128 id=128 data-nosnippet>128</a> <span class="kw">let </span>output = sentinel.scrub_text(input);
|
||||
<a href=#129 id=129 data-nosnippet>129</a> <span class="macro">assert!</span>(output.contains(<span class="string">"password: [REDACTED]"</span>));
|
||||
<a href=#130 id=130 data-nosnippet>130</a> }
|
||||
<a href=#131 id=131 data-nosnippet>131</a>
|
||||
<a href=#132 id=132 data-nosnippet>132</a> <span class="attr">#[test]
|
||||
<a href=#133 id=133 data-nosnippet>133</a> </span><span class="kw">fn </span>test_contains_secrets() {
|
||||
<a href=#134 id=134 data-nosnippet>134</a> <span class="kw">let </span>sentinel = SecretSentinel::new_default();
|
||||
<a href=#135 id=135 data-nosnippet>135</a> <span class="macro">assert!</span>(sentinel.contains_secrets(<span class="string">"AKIAIOSFODNN7EXAMPLE"</span>));
|
||||
<a href=#136 id=136 data-nosnippet>136</a> <span class="macro">assert!</span>(!sentinel.contains_secrets(<span class="string">"nothing sensitive here"</span>));
|
||||
<a href=#137 id=137 data-nosnippet>137</a> }
|
||||
<a href=#138 id=138 data-nosnippet>138</a>}</code></pre></div></section></main></body></html>
|
||||
181
target/doc/src/chrs_slurp/lib.rs.html
Normal file
181
target/doc/src/chrs_slurp/lib.rs.html
Normal file
@@ -0,0 +1,181 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `chrs-slurp/src/lib.rs`."><title>lib.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="chrs_slurp" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../../static.files/storage-82c7156e.js"></script><script defer src="../../static.files/src-script-63605ae7.js"></script><script defer src="../../src-files.js"></script><script defer src="../../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer"></div><main><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1><div class="sub-heading">chrs_slurp/</div>lib.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="doccomment">//! # chrs-slurp
|
||||
<a href=#2 id=2 data-nosnippet>2</a>//!
|
||||
<a href=#3 id=3 data-nosnippet>3</a>//! **Intelligence Crate** – Provides the *curation* layer for the CHORUS system.
|
||||
<a href=#4 id=4 data-nosnippet>4</a>//!
|
||||
<a href=#5 id=5 data-nosnippet>5</a>//! The purpose of this crate is to take **Decision Records** generated by autonomous
|
||||
<a href=#6 id=6 data-nosnippet>6</a>//! agents, validate them, and persist them into the graph database. It isolates the
|
||||
<a href=#7 id=7 data-nosnippet>7</a>//! validation and storage concerns so that other components (e.g. provenance, security)
|
||||
<a href=#8 id=8 data-nosnippet>8</a>//! can work with a clean, audited data model.
|
||||
<a href=#9 id=9 data-nosnippet>9</a>//!
|
||||
<a href=#10 id=10 data-nosnippet>10</a>//! ## Architectural Rationale
|
||||
<a href=#11 id=11 data-nosnippet>11</a>//!
|
||||
<a href=#12 id=12 data-nosnippet>12</a>//! * **Separation of concerns** – Agents produce raw decisions; this crate is the
|
||||
<a href=#13 id=13 data-nosnippet>13</a>//! single source of truth for how those decisions are stored.
|
||||
<a href=#14 id=14 data-nosnippet>14</a>//! * **Auditability** – By persisting to a Dolt‑backed graph each decision is versioned
|
||||
<a href=#15 id=15 data-nosnippet>15</a>//! and can be replay‑backed, satisfying CHORUS’s requirement for reproducible
|
||||
<a href=#16 id=16 data-nosnippet>16</a>//! reasoning.
|
||||
<a href=#17 id=17 data-nosnippet>17</a>//! * **Extensibility** – The `CurationEngine` can be extended with additional validation
|
||||
<a href=#18 id=18 data-nosnippet>18</a>//! steps (e.g. policy checks) without touching the agents themselves.
|
||||
<a href=#19 id=19 data-nosnippet>19</a>//!
|
||||
<a href=#20 id=20 data-nosnippet>20</a>//! The crate depends on:
|
||||
<a href=#21 id=21 data-nosnippet>21</a>//! * `chrs-graph` – a thin wrapper around a Dolt‑backed graph implementation.
|
||||
<a href=#22 id=22 data-nosnippet>22</a>//! * `ucxl` – for addressing external knowledge artefacts.
|
||||
<a href=#23 id=23 data-nosnippet>23</a>//! * `chrono`, `serde`, `uuid` – standard utilities for timestamps, (de)serialization
|
||||
<a href=#24 id=24 data-nosnippet>24</a>//! and unique identifiers.
|
||||
<a href=#25 id=25 data-nosnippet>25</a>//!
|
||||
<a href=#26 id=26 data-nosnippet>26</a>//! ---
|
||||
<a href=#27 id=27 data-nosnippet>27</a>//!
|
||||
<a href=#28 id=28 data-nosnippet>28</a>//! # Public API
|
||||
<a href=#29 id=29 data-nosnippet>29</a>//!
|
||||
<a href=#30 id=30 data-nosnippet>30</a>//! The public surface consists of three items:
|
||||
<a href=#31 id=31 data-nosnippet>31</a>//!
|
||||
<a href=#32 id=32 data-nosnippet>32</a>//! * `DecisionRecord` – data structure representing a curated decision.
|
||||
<a href=#33 id=33 data-nosnippet>33</a>//! * `SlurpError` – enumeration of possible errors while curating.
|
||||
<a href=#34 id=34 data-nosnippet>34</a>//! * `CurationEngine` – the engine that validates and persists `DecisionRecord`s.
|
||||
<a href=#35 id=35 data-nosnippet>35</a>//!
|
||||
<a href=#36 id=36 data-nosnippet>36</a>//! Each item is documented in‑line below.
|
||||
<a href=#37 id=37 data-nosnippet>37</a>
|
||||
<a href=#38 id=38 data-nosnippet>38</a></span><span class="kw">use </span>chrono::{DateTime, Utc};
|
||||
<a href=#39 id=39 data-nosnippet>39</a><span class="kw">use </span>chrs_graph::{DoltGraph, GraphError};
|
||||
<a href=#40 id=40 data-nosnippet>40</a><span class="kw">use </span>serde::{Deserialize, Serialize};
|
||||
<a href=#41 id=41 data-nosnippet>41</a><span class="kw">use </span>thiserror::Error;
|
||||
<a href=#42 id=42 data-nosnippet>42</a><span class="kw">use </span>ucxl::UCXLAddress;
|
||||
<a href=#43 id=43 data-nosnippet>43</a><span class="kw">use </span>uuid::Uuid;
|
||||
<a href=#44 id=44 data-nosnippet>44</a>
|
||||
<a href=#45 id=45 data-nosnippet>45</a><span class="doccomment">/// A record representing a curated decision within the CHORUS system.
|
||||
<a href=#46 id=46 data-nosnippet>46</a>///
|
||||
<a href=#47 id=47 data-nosnippet>47</a>/// # What
|
||||
<a href=#48 id=48 data-nosnippet>48</a>///
|
||||
<a href=#49 id=49 data-nosnippet>49</a>/// This struct captures the essential metadata of a decision made by an
|
||||
<a href=#50 id=50 data-nosnippet>50</a>/// autonomous agent, including who authored it, the reasoning behind it, any
|
||||
<a href=#51 id=51 data-nosnippet>51</a>/// citations to external knowledge, and a timestamp.
|
||||
<a href=#52 id=52 data-nosnippet>52</a>///
|
||||
<a href=#53 id=53 data-nosnippet>53</a>/// # Why
|
||||
<a href=#54 id=54 data-nosnippet>54</a>///
|
||||
<a href=#55 id=55 data-nosnippet>55</a>/// Decision records are persisted in the graph database so that downstream
|
||||
<a href=#56 id=56 data-nosnippet>56</a>/// components (e.g., provenance analysis) can reason about the provenance and
|
||||
<a href=#57 id=57 data-nosnippet>57</a>/// justification of actions. Storing them as a dedicated table enables
|
||||
<a href=#58 id=58 data-nosnippet>58</a>/// reproducibility and auditability across the CHORUS architecture.
|
||||
<a href=#59 id=59 data-nosnippet>59</a></span><span class="attr">#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
<a href=#60 id=60 data-nosnippet>60</a></span><span class="kw">pub struct </span>DecisionRecord {
|
||||
<a href=#61 id=61 data-nosnippet>61</a> <span class="doccomment">/// Unique identifier for the decision.
|
||||
<a href=#62 id=62 data-nosnippet>62</a> </span><span class="kw">pub </span>id: Uuid,
|
||||
<a href=#63 id=63 data-nosnippet>63</a> <span class="doccomment">/// Identifier of the agent or human that authored the decision.
|
||||
<a href=#64 id=64 data-nosnippet>64</a> </span><span class="kw">pub </span>author: String,
|
||||
<a href=#65 id=65 data-nosnippet>65</a> <span class="doccomment">/// Free‑form textual reasoning explaining the decision.
|
||||
<a href=#66 id=66 data-nosnippet>66</a> </span><span class="kw">pub </span>reasoning: String,
|
||||
<a href=#67 id=67 data-nosnippet>67</a> <span class="doccomment">/// Serialized UCXL addresses that serve as citations for the decision.
|
||||
<a href=#68 id=68 data-nosnippet>68</a> /// Each entry should be a valid `UCXLAddress` string.
|
||||
<a href=#69 id=69 data-nosnippet>69</a> </span><span class="kw">pub </span>citations: Vec<String>,
|
||||
<a href=#70 id=70 data-nosnippet>70</a> <span class="doccomment">/// The moment the decision was created.
|
||||
<a href=#71 id=71 data-nosnippet>71</a> </span><span class="kw">pub </span>timestamp: DateTime<Utc>,
|
||||
<a href=#72 id=72 data-nosnippet>72</a>}
|
||||
<a href=#73 id=73 data-nosnippet>73</a>
|
||||
<a href=#74 id=74 data-nosnippet>74</a><span class="doccomment">/// Errors that can arise while slurping (curating) a decision record.
|
||||
<a href=#75 id=75 data-nosnippet>75</a>///
|
||||
<a href=#76 id=76 data-nosnippet>76</a>/// * `Graph` – underlying graph database operation failed.
|
||||
<a href=#77 id=77 data-nosnippet>77</a>/// * `Serde` – (de)serialization of the decision data failed.
|
||||
<a href=#78 id=78 data-nosnippet>78</a>/// * `ValidationError` – a supplied citation could not be parsed as a
|
||||
<a href=#79 id=79 data-nosnippet>79</a>/// `UCXLAddress`.
|
||||
<a href=#80 id=80 data-nosnippet>80</a></span><span class="attr">#[derive(Debug, Error)]
|
||||
<a href=#81 id=81 data-nosnippet>81</a></span><span class="kw">pub enum </span>SlurpError {
|
||||
<a href=#82 id=82 data-nosnippet>82</a> <span class="attr">#[error(<span class="string">"Graph error: {0}"</span>)]
|
||||
<a href=#83 id=83 data-nosnippet>83</a> </span>Graph(<span class="attr">#[from] </span>GraphError),
|
||||
<a href=#84 id=84 data-nosnippet>84</a> <span class="attr">#[error(<span class="string">"Serialization error: {0}"</span>)]
|
||||
<a href=#85 id=85 data-nosnippet>85</a> </span>Serde(<span class="attr">#[from] </span>serde_json::Error),
|
||||
<a href=#86 id=86 data-nosnippet>86</a> <span class="attr">#[error(<span class="string">"Validation error: {0}"</span>)]
|
||||
<a href=#87 id=87 data-nosnippet>87</a> </span>ValidationError(String),
|
||||
<a href=#88 id=88 data-nosnippet>88</a>}
|
||||
<a href=#89 id=89 data-nosnippet>89</a>
|
||||
<a href=#90 id=90 data-nosnippet>90</a><span class="doccomment">/// Core engine that validates and persists `DecisionRecord`s into the
|
||||
<a href=#91 id=91 data-nosnippet>91</a>/// Dolt‑backed graph.
|
||||
<a href=#92 id=92 data-nosnippet>92</a>///
|
||||
<a href=#93 id=93 data-nosnippet>93</a>/// # Why
|
||||
<a href=#94 id=94 data-nosnippet>94</a>///
|
||||
<a href=#95 id=95 data-nosnippet>95</a>/// Centralising curation logic ensures a single place for validation and
|
||||
<a href=#96 id=96 data-nosnippet>96</a>/// storage semantics, keeping the rest of the codebase agnostic of the graph
|
||||
<a href=#97 id=97 data-nosnippet>97</a>/// implementation details.
|
||||
<a href=#98 id=98 data-nosnippet>98</a></span><span class="kw">pub struct </span>CurationEngine {
|
||||
<a href=#99 id=99 data-nosnippet>99</a> graph: DoltGraph,
|
||||
<a href=#100 id=100 data-nosnippet>100</a>}
|
||||
<a href=#101 id=101 data-nosnippet>101</a>
|
||||
<a href=#102 id=102 data-nosnippet>102</a><span class="kw">impl </span>CurationEngine {
|
||||
<a href=#103 id=103 data-nosnippet>103</a> <span class="doccomment">/// Creates a new `CurationEngine` bound to the supplied `DoltGraph`.
|
||||
<a href=#104 id=104 data-nosnippet>104</a> ///
|
||||
<a href=#105 id=105 data-nosnippet>105</a> /// The engine holds a reference to the graph for the lifetime of the
|
||||
<a href=#106 id=106 data-nosnippet>106</a> /// instance; callers are responsible for providing a correctly initialised
|
||||
<a href=#107 id=107 data-nosnippet>107</a> /// graph.
|
||||
<a href=#108 id=108 data-nosnippet>108</a> </span><span class="kw">pub fn </span>new(graph: DoltGraph) -> <span class="self">Self </span>{
|
||||
<a href=#109 id=109 data-nosnippet>109</a> <span class="self">Self </span>{ graph }
|
||||
<a href=#110 id=110 data-nosnippet>110</a> }
|
||||
<a href=#111 id=111 data-nosnippet>111</a>
|
||||
<a href=#112 id=112 data-nosnippet>112</a> <span class="doccomment">/// Validates the citations in `dr` and persists the decision into the
|
||||
<a href=#113 id=113 data-nosnippet>113</a> /// graph.
|
||||
<a href=#114 id=114 data-nosnippet>114</a> ///
|
||||
<a href=#115 id=115 data-nosnippet>115</a> /// The method performs three steps:
|
||||
<a href=#116 id=116 data-nosnippet>116</a> /// 1. **Citation validation** – each citation string is parsed into a
|
||||
<a href=#117 id=117 data-nosnippet>117</a> /// `UCXLAddress`. Invalid citations produce a `ValidationError`.
|
||||
<a href=#118 id=118 data-nosnippet>118</a> /// 2. **Table assurance** – attempts to create the `curated_decisions`
|
||||
<a href=#119 id=119 data-nosnippet>119</a> /// table if it does not already exist. Errors are ignored because the
|
||||
<a href=#120 id=120 data-nosnippet>120</a> /// table may already be present.
|
||||
<a href=#121 id=121 data-nosnippet>121</a> /// 3. **Insertion & commit** – the decision is serialised to JSON and
|
||||
<a href=#122 id=122 data-nosnippet>122</a> /// inserted as a node, then the graph transaction is committed.
|
||||
<a href=#123 id=123 data-nosnippet>123</a> ///
|
||||
<a href=#124 id=124 data-nosnippet>124</a> /// # Errors
|
||||
<a href=#125 id=125 data-nosnippet>125</a> /// Propagates any `GraphError`, `serde_json::Error`, or custom
|
||||
<a href=#126 id=126 data-nosnippet>126</a> /// validation failures.
|
||||
<a href=#127 id=127 data-nosnippet>127</a> </span><span class="kw">pub fn </span>curate_decision(<span class="kw-2">&</span><span class="self">self</span>, dr: DecisionRecord) -> <span class="prelude-ty">Result</span><(), SlurpError> {
|
||||
<a href=#128 id=128 data-nosnippet>128</a> <span class="comment">// 1. Validate Citations
|
||||
<a href=#129 id=129 data-nosnippet>129</a> </span><span class="kw">for </span>citation <span class="kw">in </span><span class="kw-2">&</span>dr.citations {
|
||||
<a href=#130 id=130 data-nosnippet>130</a> <span class="kw">use </span>std::str::FromStr;
|
||||
<a href=#131 id=131 data-nosnippet>131</a> UCXLAddress::from_str(citation).map_err(|e| {
|
||||
<a href=#132 id=132 data-nosnippet>132</a> SlurpError::ValidationError(<span class="macro">format!</span>(<span class="string">"Invalid citation {}: {}"</span>, citation, e))
|
||||
<a href=#133 id=133 data-nosnippet>133</a> })<span class="question-mark">?</span>;
|
||||
<a href=#134 id=134 data-nosnippet>134</a> }
|
||||
<a href=#135 id=135 data-nosnippet>135</a>
|
||||
<a href=#136 id=136 data-nosnippet>136</a> <span class="comment">// 2. Ensure the table exists; ignore error if it already does.
|
||||
<a href=#137 id=137 data-nosnippet>137</a> </span><span class="kw">let _ </span>= <span class="self">self</span>.graph.create_table(
|
||||
<a href=#138 id=138 data-nosnippet>138</a> <span class="string">"curated_decisions"</span>,
|
||||
<a href=#139 id=139 data-nosnippet>139</a> <span class="string">"id VARCHAR(255) PRIMARY KEY, author TEXT, reasoning TEXT, citations TEXT, curated_at TEXT"</span>,
|
||||
<a href=#140 id=140 data-nosnippet>140</a> );
|
||||
<a href=#141 id=141 data-nosnippet>141</a>
|
||||
<a href=#142 id=142 data-nosnippet>142</a> <span class="comment">// 3. Serialize the record and insert it.
|
||||
<a href=#143 id=143 data-nosnippet>143</a> </span><span class="kw">let </span>data = <span class="macro">serde_json::json!</span>({
|
||||
<a href=#144 id=144 data-nosnippet>144</a> <span class="string">"id"</span>: dr.id.to_string(),
|
||||
<a href=#145 id=145 data-nosnippet>145</a> <span class="string">"author"</span>: dr.author,
|
||||
<a href=#146 id=146 data-nosnippet>146</a> <span class="string">"reasoning"</span>: dr.reasoning,
|
||||
<a href=#147 id=147 data-nosnippet>147</a> <span class="string">"citations"</span>: serde_json::to_string(<span class="kw-2">&</span>dr.citations)<span class="question-mark">?</span>,
|
||||
<a href=#148 id=148 data-nosnippet>148</a> <span class="string">"curated_at"</span>: dr.timestamp.to_rfc3339(),
|
||||
<a href=#149 id=149 data-nosnippet>149</a> });
|
||||
<a href=#150 id=150 data-nosnippet>150</a>
|
||||
<a href=#151 id=151 data-nosnippet>151</a> <span class="self">self</span>.graph.insert_node(<span class="string">"curated_decisions"</span>, data)<span class="question-mark">?</span>;
|
||||
<a href=#152 id=152 data-nosnippet>152</a> <span class="self">self</span>.graph
|
||||
<a href=#153 id=153 data-nosnippet>153</a> .commit(<span class="kw-2">&</span><span class="macro">format!</span>(<span class="string">"Curation complete for DR: {}"</span>, dr.id))<span class="question-mark">?</span>;
|
||||
<a href=#154 id=154 data-nosnippet>154</a> <span class="prelude-val">Ok</span>(())
|
||||
<a href=#155 id=155 data-nosnippet>155</a> }
|
||||
<a href=#156 id=156 data-nosnippet>156</a>}
|
||||
<a href=#157 id=157 data-nosnippet>157</a>
|
||||
<a href=#158 id=158 data-nosnippet>158</a><span class="attr">#[cfg(test)]
|
||||
<a href=#159 id=159 data-nosnippet>159</a></span><span class="kw">mod </span>tests {
|
||||
<a href=#160 id=160 data-nosnippet>160</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
|
||||
<a href=#161 id=161 data-nosnippet>161</a> <span class="kw">use </span>tempfile::TempDir;
|
||||
<a href=#162 id=162 data-nosnippet>162</a>
|
||||
<a href=#163 id=163 data-nosnippet>163</a> <span class="doccomment">/// Integration test that exercises the full curation flow on a temporary
|
||||
<a href=#164 id=164 data-nosnippet>164</a> /// Dolt graph.
|
||||
<a href=#165 id=165 data-nosnippet>165</a> </span><span class="attr">#[test]
|
||||
<a href=#166 id=166 data-nosnippet>166</a> </span><span class="kw">fn </span>test_curation_flow() {
|
||||
<a href=#167 id=167 data-nosnippet>167</a> <span class="kw">let </span>dir = TempDir::new().unwrap();
|
||||
<a href=#168 id=168 data-nosnippet>168</a> <span class="kw">let </span>graph = DoltGraph::init(dir.path()).expect(<span class="string">"graph init failed"</span>);
|
||||
<a href=#169 id=169 data-nosnippet>169</a> <span class="kw">let </span>engine = CurationEngine::new(graph);
|
||||
<a href=#170 id=170 data-nosnippet>170</a>
|
||||
<a href=#171 id=171 data-nosnippet>171</a> <span class="kw">let </span>dr = DecisionRecord {
|
||||
<a href=#172 id=172 data-nosnippet>172</a> id: Uuid::new_v4(),
|
||||
<a href=#173 id=173 data-nosnippet>173</a> author: <span class="string">"agent-001"</span>.into(),
|
||||
<a href=#174 id=174 data-nosnippet>174</a> reasoning: <span class="string">"Tested the implementation of SLURP."</span>.into(),
|
||||
<a href=#175 id=175 data-nosnippet>175</a> citations: <span class="macro">vec!</span>[<span class="string">"ucxl://system:watcher@local:filesystem/#/UCXL/src/lib.rs"</span>.into()],
|
||||
<a href=#176 id=176 data-nosnippet>176</a> timestamp: Utc::now(),
|
||||
<a href=#177 id=177 data-nosnippet>177</a> };
|
||||
<a href=#178 id=178 data-nosnippet>178</a>
|
||||
<a href=#179 id=179 data-nosnippet>179</a> engine.curate_decision(dr).expect(<span class="string">"curation failed"</span>);
|
||||
<a href=#180 id=180 data-nosnippet>180</a> }
|
||||
<a href=#181 id=181 data-nosnippet>181</a>}</code></pre></div></section></main></body></html>
|
||||
116
target/doc/src/chrs_sync/lib.rs.html
Normal file
116
target/doc/src/chrs_sync/lib.rs.html
Normal file
@@ -0,0 +1,116 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `chrs-sync/src/lib.rs`."><title>lib.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="chrs_sync" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../../static.files/storage-82c7156e.js"></script><script defer src="../../static.files/src-script-63605ae7.js"></script><script defer src="../../src-files.js"></script><script defer src="../../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer"></div><main><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1><div class="sub-heading">chrs_sync/</div>lib.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="kw">use </span>chrono::Utc;
|
||||
<a href=#2 id=2 data-nosnippet>2</a><span class="doccomment">/// chrs-sync crate provides synchronization utilities for the CHORUS system.
|
||||
<a href=#3 id=3 data-nosnippet>3</a>///
|
||||
<a href=#4 id=4 data-nosnippet>4</a>/// It uses a `Mailbox` for message passing between peers and a Dolt repository
|
||||
<a href=#5 id=5 data-nosnippet>5</a>/// to track state hashes. The primary abstraction is `SyncManager`, which can
|
||||
<a href=#6 id=6 data-nosnippet>6</a>/// broadcast the current repository hash to peers and handle incoming sync
|
||||
<a href=#7 id=7 data-nosnippet>7</a>/// signals.
|
||||
<a href=#8 id=8 data-nosnippet>8</a></span><span class="kw">use </span>chrs_mail::{Mailbox, Message};
|
||||
<a href=#9 id=9 data-nosnippet>9</a><span class="kw">use </span>std::path::PathBuf;
|
||||
<a href=#10 id=10 data-nosnippet>10</a><span class="kw">use </span>std::process::Command;
|
||||
<a href=#11 id=11 data-nosnippet>11</a><span class="kw">use </span>uuid::Uuid;
|
||||
<a href=#12 id=12 data-nosnippet>12</a>
|
||||
<a href=#13 id=13 data-nosnippet>13</a><span class="doccomment">/// Manages synchronization of a Dolt repository across peers.
|
||||
<a href=#14 id=14 data-nosnippet>14</a>///
|
||||
<a href=#15 id=15 data-nosnippet>15</a>/// # Fields
|
||||
<a href=#16 id=16 data-nosnippet>16</a>/// * `mailbox` – The `Mailbox` instance used to send and receive messages.
|
||||
<a href=#17 id=17 data-nosnippet>17</a>/// * `repo_path` – Filesystem path to the local Dolt repository.
|
||||
<a href=#18 id=18 data-nosnippet>18</a>///
|
||||
<a href=#19 id=19 data-nosnippet>19</a>/// # Rationale
|
||||
<a href=#20 id=20 data-nosnippet>20</a>/// The CHORUS architecture relies on deterministic state replication. By
|
||||
<a href=#21 id=21 data-nosnippet>21</a>/// broadcasting the latest commit hash (`sync_signal`) each peer can decide
|
||||
<a href=#22 id=22 data-nosnippet>22</a>/// whether to pull updates. This struct encapsulates that behaviour, keeping the
|
||||
<a href=#23 id=23 data-nosnippet>23</a>/// rest of the system agnostic of the underlying VCS commands.
|
||||
<a href=#24 id=24 data-nosnippet>24</a></span><span class="kw">pub struct </span>SyncManager {
|
||||
<a href=#25 id=25 data-nosnippet>25</a> mailbox: Mailbox,
|
||||
<a href=#26 id=26 data-nosnippet>26</a> repo_path: PathBuf,
|
||||
<a href=#27 id=27 data-nosnippet>27</a>}
|
||||
<a href=#28 id=28 data-nosnippet>28</a>
|
||||
<a href=#29 id=29 data-nosnippet>29</a><span class="kw">impl </span>SyncManager {
|
||||
<a href=#30 id=30 data-nosnippet>30</a> <span class="doccomment">/// Creates a new `SyncManager`.
|
||||
<a href=#31 id=31 data-nosnippet>31</a> ///
|
||||
<a href=#32 id=32 data-nosnippet>32</a> /// # Parameters
|
||||
<a href=#33 id=33 data-nosnippet>33</a> /// * `mailbox` – An already‑opened `Mailbox` for peer communication.
|
||||
<a href=#34 id=34 data-nosnippet>34</a> /// * `repo_path` – Path to the Dolt repository that should be kept in sync.
|
||||
<a href=#35 id=35 data-nosnippet>35</a> ///
|
||||
<a href=#36 id=36 data-nosnippet>36</a> /// Returns a fully‑initialised manager ready to broadcast or handle sync
|
||||
<a href=#37 id=37 data-nosnippet>37</a> /// signals.
|
||||
<a href=#38 id=38 data-nosnippet>38</a> </span><span class="kw">pub fn </span>new(mailbox: Mailbox, repo_path: PathBuf) -> <span class="self">Self </span>{
|
||||
<a href=#39 id=39 data-nosnippet>39</a> <span class="self">Self </span>{ mailbox, repo_path }
|
||||
<a href=#40 id=40 data-nosnippet>40</a> }
|
||||
<a href=#41 id=41 data-nosnippet>41</a>
|
||||
<a href=#42 id=42 data-nosnippet>42</a> <span class="doccomment">/// Broadcasts the current repository state to a remote peer.
|
||||
<a href=#43 id=43 data-nosnippet>43</a> ///
|
||||
<a href=#44 id=44 data-nosnippet>44</a> /// The method executes `dolt log -n 1 --format %H` to obtain the most recent
|
||||
<a href=#45 id=45 data-nosnippet>45</a> /// commit hash, constructs a `Message` with topic `"sync_signal"` and sends it
|
||||
<a href=#46 id=46 data-nosnippet>46</a> /// via the mailbox.
|
||||
<a href=#47 id=47 data-nosnippet>47</a> ///
|
||||
<a href=#48 id=48 data-nosnippet>48</a> /// * `from_peer` – Identifier of the sender.
|
||||
<a href=#49 id=49 data-nosnippet>49</a> /// * `to_peer` – Identifier of the intended recipient.
|
||||
<a href=#50 id=50 data-nosnippet>50</a> ///
|
||||
<a href=#51 id=51 data-nosnippet>51</a> /// # Errors
|
||||
<a href=#52 id=52 data-nosnippet>52</a> /// Returns any I/O or command‑execution error wrapped in a boxed `dyn
|
||||
<a href=#53 id=53 data-nosnippet>53</a> /// Error`.
|
||||
<a href=#54 id=54 data-nosnippet>54</a> </span><span class="kw">pub fn </span>broadcast_state(
|
||||
<a href=#55 id=55 data-nosnippet>55</a> <span class="kw-2">&</span><span class="self">self</span>,
|
||||
<a href=#56 id=56 data-nosnippet>56</a> from_peer: <span class="kw-2">&</span>str,
|
||||
<a href=#57 id=57 data-nosnippet>57</a> to_peer: <span class="kw-2">&</span>str,
|
||||
<a href=#58 id=58 data-nosnippet>58</a> ) -> <span class="prelude-ty">Result</span><(), Box<<span class="kw">dyn </span>std::error::Error>> {
|
||||
<a href=#59 id=59 data-nosnippet>59</a> <span class="comment">// Get current dolt hash
|
||||
<a href=#60 id=60 data-nosnippet>60</a> </span><span class="kw">let </span>output = Command::new(<span class="string">"dolt"</span>)
|
||||
<a href=#61 id=61 data-nosnippet>61</a> .args(<span class="kw-2">&</span>[<span class="string">"log"</span>, <span class="string">"-n"</span>, <span class="string">"1"</span>, <span class="string">"--format"</span>, <span class="string">"%H"</span>])
|
||||
<a href=#62 id=62 data-nosnippet>62</a> .current_dir(<span class="kw-2">&</span><span class="self">self</span>.repo_path)
|
||||
<a href=#63 id=63 data-nosnippet>63</a> .output()<span class="question-mark">?</span>;
|
||||
<a href=#64 id=64 data-nosnippet>64</a>
|
||||
<a href=#65 id=65 data-nosnippet>65</a> <span class="kw">let </span>current_hash = String::from_utf8_lossy(<span class="kw-2">&</span>output.stdout).trim().to_string();
|
||||
<a href=#66 id=66 data-nosnippet>66</a>
|
||||
<a href=#67 id=67 data-nosnippet>67</a> <span class="kw">let </span>msg = Message {
|
||||
<a href=#68 id=68 data-nosnippet>68</a> id: Uuid::new_v4(),
|
||||
<a href=#69 id=69 data-nosnippet>69</a> from_peer: from_peer.into(),
|
||||
<a href=#70 id=70 data-nosnippet>70</a> to_peer: to_peer.into(),
|
||||
<a href=#71 id=71 data-nosnippet>71</a> topic: <span class="string">"sync_signal"</span>.into(),
|
||||
<a href=#72 id=72 data-nosnippet>72</a> payload: <span class="macro">serde_json::json!</span>({ <span class="string">"commit_hash"</span>: current_hash }),
|
||||
<a href=#73 id=73 data-nosnippet>73</a> sent_at: Utc::now(),
|
||||
<a href=#74 id=74 data-nosnippet>74</a> read_at: <span class="prelude-val">None</span>,
|
||||
<a href=#75 id=75 data-nosnippet>75</a> };
|
||||
<a href=#76 id=76 data-nosnippet>76</a>
|
||||
<a href=#77 id=77 data-nosnippet>77</a> <span class="self">self</span>.mailbox.send(<span class="kw-2">&</span>msg)<span class="question-mark">?</span>;
|
||||
<a href=#78 id=78 data-nosnippet>78</a> <span class="macro">println!</span>(
|
||||
<a href=#79 id=79 data-nosnippet>79</a> <span class="string">"Broadcasted sync signal: {} from {}"</span>,
|
||||
<a href=#80 id=80 data-nosnippet>80</a> current_hash, from_peer
|
||||
<a href=#81 id=81 data-nosnippet>81</a> );
|
||||
<a href=#82 id=82 data-nosnippet>82</a> <span class="prelude-val">Ok</span>(())
|
||||
<a href=#83 id=83 data-nosnippet>83</a> }
|
||||
<a href=#84 id=84 data-nosnippet>84</a>
|
||||
<a href=#85 id=85 data-nosnippet>85</a> <span class="doccomment">/// Handles an incoming `sync_signal` message.
|
||||
<a href=#86 id=86 data-nosnippet>86</a> ///
|
||||
<a href=#87 id=87 data-nosnippet>87</a> /// If the message topic is not `"sync_signal"` the function returns `Ok(())`
|
||||
<a href=#88 id=88 data-nosnippet>88</a> /// immediately. Otherwise it extracts the remote commit hash and attempts a
|
||||
<a href=#89 id=89 data-nosnippet>89</a> /// `dolt pull origin` to bring the local repository up‑to‑date. In a real
|
||||
<a href=#90 id=90 data-nosnippet>90</a> /// P2P deployment the remote URL would be derived from the sender, but the
|
||||
<a href=#91 id=91 data-nosnippet>91</a> /// current implementation uses the default remote configuration.
|
||||
<a href=#92 id=92 data-nosnippet>92</a> ///
|
||||
<a href=#93 id=93 data-nosnippet>93</a> /// # Errors
|
||||
<a href=#94 id=94 data-nosnippet>94</a> /// Propagates any command execution failures.
|
||||
<a href=#95 id=95 data-nosnippet>95</a> </span><span class="kw">pub fn </span>handle_sync_signal(<span class="kw-2">&</span><span class="self">self</span>, msg: <span class="kw-2">&</span>Message) -> <span class="prelude-ty">Result</span><(), Box<<span class="kw">dyn </span>std::error::Error>> {
|
||||
<a href=#96 id=96 data-nosnippet>96</a> <span class="kw">if </span>msg.topic != <span class="string">"sync_signal" </span>{
|
||||
<a href=#97 id=97 data-nosnippet>97</a> <span class="kw">return </span><span class="prelude-val">Ok</span>(());
|
||||
<a href=#98 id=98 data-nosnippet>98</a> }
|
||||
<a href=#99 id=99 data-nosnippet>99</a>
|
||||
<a href=#100 id=100 data-nosnippet>100</a> <span class="kw">let </span>remote_hash = msg.payload[<span class="string">"commit_hash"</span>].as_str().unwrap_or_default();
|
||||
<a href=#101 id=101 data-nosnippet>101</a> <span class="macro">println!</span>(<span class="string">"Received sync signal for hash: {}"</span>, remote_hash);
|
||||
<a href=#102 id=102 data-nosnippet>102</a>
|
||||
<a href=#103 id=103 data-nosnippet>103</a> <span class="comment">// In a real P2P scenario, we would pull from the remote peer's URL.
|
||||
<a href=#104 id=104 data-nosnippet>104</a> // For now, we simulate by attempting a 'dolt pull' if a remote is configured.
|
||||
<a href=#105 id=105 data-nosnippet>105</a> </span><span class="kw">let </span>status = Command::new(<span class="string">"dolt"</span>)
|
||||
<a href=#106 id=106 data-nosnippet>106</a> .args(<span class="kw-2">&</span>[<span class="string">"pull"</span>, <span class="string">"origin"</span>])
|
||||
<a href=#107 id=107 data-nosnippet>107</a> .current_dir(<span class="kw-2">&</span><span class="self">self</span>.repo_path)
|
||||
<a href=#108 id=108 data-nosnippet>108</a> .status()<span class="question-mark">?</span>;
|
||||
<a href=#109 id=109 data-nosnippet>109</a>
|
||||
<a href=#110 id=110 data-nosnippet>110</a> <span class="kw">if </span>status.success() {
|
||||
<a href=#111 id=111 data-nosnippet>111</a> <span class="macro">println!</span>(<span class="string">"Successfully pulled updates for hash: {}"</span>, remote_hash);
|
||||
<a href=#112 id=112 data-nosnippet>112</a> }
|
||||
<a href=#113 id=113 data-nosnippet>113</a>
|
||||
<a href=#114 id=114 data-nosnippet>114</a> <span class="prelude-val">Ok</span>(())
|
||||
<a href=#115 id=115 data-nosnippet>115</a> }
|
||||
<a href=#116 id=116 data-nosnippet>116</a>}</code></pre></div></section></main></body></html>
|
||||
301
target/doc/src/ucxl/lib.rs.html
Normal file
301
target/doc/src/ucxl/lib.rs.html
Normal file
@@ -0,0 +1,301 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `UCXL/src/lib.rs`."><title>lib.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="ucxl" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../../static.files/storage-82c7156e.js"></script><script defer src="../../static.files/src-script-63605ae7.js"></script><script defer src="../../src-files.js"></script><script defer src="../../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer"></div><main><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1><div class="sub-heading">ucxl/</div>lib.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="doccomment">//! UCXL core data structures and utilities.
|
||||
<a href=#2 id=2 data-nosnippet>2</a>//!
|
||||
<a href=#3 id=3 data-nosnippet>3</a>//! This module provides the fundamental types used throughout the CHORUS
|
||||
<a href=#4 id=4 data-nosnippet>4</a>//! system for addressing resources (UCXL addresses), handling temporal axes,
|
||||
<a href=#5 id=5 data-nosnippet>5</a>//! and storing lightweight metadata. The implementation is deliberately
|
||||
<a href=#6 id=6 data-nosnippet>6</a>//! lightweight and in‑memory to keep the core fast and dependency‑free.
|
||||
<a href=#7 id=7 data-nosnippet>7</a>
|
||||
<a href=#8 id=8 data-nosnippet>8</a></span><span class="kw">pub mod </span>watcher;
|
||||
<a href=#9 id=9 data-nosnippet>9</a>
|
||||
<a href=#10 id=10 data-nosnippet>10</a><span class="kw">use </span>std::collections::HashMap;
|
||||
<a href=#11 id=11 data-nosnippet>11</a><span class="kw">use </span>std::fmt;
|
||||
<a href=#12 id=12 data-nosnippet>12</a><span class="kw">use </span>std::str::FromStr;
|
||||
<a href=#13 id=13 data-nosnippet>13</a>
|
||||
<a href=#14 id=14 data-nosnippet>14</a><span class="doccomment">/// Represents the temporal axis in a UCXL address.
|
||||
<a href=#15 id=15 data-nosnippet>15</a>///
|
||||
<a href=#16 id=16 data-nosnippet>16</a>/// **What**: An enumeration of the three supported temporal positions –
|
||||
<a href=#17 id=17 data-nosnippet>17</a>/// present, past, and future – each represented by a symbolic string in the
|
||||
<a href=#18 id=18 data-nosnippet>18</a>/// address format.
|
||||
<a href=#19 id=19 data-nosnippet>19</a>///
|
||||
<a href=#20 id=20 data-nosnippet>20</a>/// **How**: The enum derives `Debug`, `PartialEq`, `Eq`, `Clone`, and `Copy`
|
||||
<a href=#21 id=21 data-nosnippet>21</a>/// for ergonomic usage. Conversions to and from strings are provided via the
|
||||
<a href=#22 id=22 data-nosnippet>22</a>/// `FromStr` and `fmt::Display` implementations.
|
||||
<a href=#23 id=23 data-nosnippet>23</a>///
|
||||
<a href=#24 id=24 data-nosnippet>24</a>/// **Why**: Temporal axes enable UCXL to refer to data at different points in
|
||||
<a href=#25 id=25 data-nosnippet>25</a>/// time (e.g. versioned resources). The simple three‑state model matches the
|
||||
<a href=#26 id=26 data-nosnippet>26</a>/// CHURUS architectural decision to keep addressing lightweight while still
|
||||
<a href=#27 id=27 data-nosnippet>27</a>/// supporting historical and speculative queries.
|
||||
<a href=#28 id=28 data-nosnippet>28</a></span><span class="attr">#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
<a href=#29 id=29 data-nosnippet>29</a></span><span class="kw">pub enum </span>TemporalAxis {
|
||||
<a href=#30 id=30 data-nosnippet>30</a> <span class="doccomment">/// Present ("#") – the current version of a resource.
|
||||
<a href=#31 id=31 data-nosnippet>31</a> </span>Present,
|
||||
<a href=#32 id=32 data-nosnippet>32</a> <span class="doccomment">/// Past ("~~") – a historical snapshot of a resource.
|
||||
<a href=#33 id=33 data-nosnippet>33</a> </span>Past,
|
||||
<a href=#34 id=34 data-nosnippet>34</a> <span class="doccomment">/// Future ("^^") – a speculative or planned version of a resource.
|
||||
<a href=#35 id=35 data-nosnippet>35</a> </span>Future,
|
||||
<a href=#36 id=36 data-nosnippet>36</a>}
|
||||
<a href=#37 id=37 data-nosnippet>37</a>
|
||||
<a href=#38 id=38 data-nosnippet>38</a><span class="kw">impl </span>FromStr <span class="kw">for </span>TemporalAxis {
|
||||
<a href=#39 id=39 data-nosnippet>39</a> <span class="kw">type </span><span class="prelude-val">Err </span>= String;
|
||||
<a href=#40 id=40 data-nosnippet>40</a> <span class="doccomment">/// Parses a temporal axis token from its textual representation.
|
||||
<a href=#41 id=41 data-nosnippet>41</a> ///
|
||||
<a href=#42 id=42 data-nosnippet>42</a> /// **What**: Accepts "#", "~~" or "^^" and maps them to the corresponding
|
||||
<a href=#43 id=43 data-nosnippet>43</a> /// enum variant.
|
||||
<a href=#44 id=44 data-nosnippet>44</a> ///
|
||||
<a href=#45 id=45 data-nosnippet>45</a> /// **How**: A simple `match` statement is used; an error string is
|
||||
<a href=#46 id=46 data-nosnippet>46</a> /// returned for any unrecognised token.
|
||||
<a href=#47 id=47 data-nosnippet>47</a> ///
|
||||
<a href=#48 id=48 data-nosnippet>48</a> /// **Why**: Centralises validation of temporal markers used throughout the
|
||||
<a href=#49 id=49 data-nosnippet>49</a> /// address parsing logic, ensuring consistency.
|
||||
<a href=#50 id=50 data-nosnippet>50</a> </span><span class="kw">fn </span>from_str(s: <span class="kw-2">&</span>str) -> <span class="prelude-ty">Result</span><<span class="self">Self</span>, <span class="self">Self</span>::Err> {
|
||||
<a href=#51 id=51 data-nosnippet>51</a> <span class="kw">match </span>s {
|
||||
<a href=#52 id=52 data-nosnippet>52</a> <span class="string">"#" </span>=> <span class="prelude-val">Ok</span>(TemporalAxis::Present),
|
||||
<a href=#53 id=53 data-nosnippet>53</a> <span class="string">"~~" </span>=> <span class="prelude-val">Ok</span>(TemporalAxis::Past),
|
||||
<a href=#54 id=54 data-nosnippet>54</a> <span class="string">"^^" </span>=> <span class="prelude-val">Ok</span>(TemporalAxis::Future),
|
||||
<a href=#55 id=55 data-nosnippet>55</a> <span class="kw">_ </span>=> <span class="prelude-val">Err</span>(<span class="macro">format!</span>(<span class="string">"Invalid temporal axis: {}"</span>, s)),
|
||||
<a href=#56 id=56 data-nosnippet>56</a> }
|
||||
<a href=#57 id=57 data-nosnippet>57</a> }
|
||||
<a href=#58 id=58 data-nosnippet>58</a>}
|
||||
<a href=#59 id=59 data-nosnippet>59</a>
|
||||
<a href=#60 id=60 data-nosnippet>60</a><span class="kw">impl </span>fmt::Display <span class="kw">for </span>TemporalAxis {
|
||||
<a href=#61 id=61 data-nosnippet>61</a> <span class="doccomment">/// Formats the temporal axis back to its string token.
|
||||
<a href=#62 id=62 data-nosnippet>62</a> ///
|
||||
<a href=#63 id=63 data-nosnippet>63</a> /// **What**: Returns "#", "~~" or "^^" depending on the variant.
|
||||
<a href=#64 id=64 data-nosnippet>64</a> ///
|
||||
<a href=#65 id=65 data-nosnippet>65</a> /// **How**: Matches on `self` and writes the corresponding string to the
|
||||
<a href=#66 id=66 data-nosnippet>66</a> /// formatter.
|
||||
<a href=#67 id=67 data-nosnippet>67</a> ///
|
||||
<a href=#68 id=68 data-nosnippet>68</a> /// **Why**: Required for serialising a `UCXLAddress` back to its textual
|
||||
<a href=#69 id=69 data-nosnippet>69</a> /// representation.
|
||||
<a href=#70 id=70 data-nosnippet>70</a> </span><span class="kw">fn </span>fmt(<span class="kw-2">&</span><span class="self">self</span>, f: <span class="kw-2">&mut </span>fmt::Formatter<<span class="lifetime">'_</span>>) -> fmt::Result {
|
||||
<a href=#71 id=71 data-nosnippet>71</a> <span class="kw">let </span>s = <span class="kw">match </span><span class="self">self </span>{
|
||||
<a href=#72 id=72 data-nosnippet>72</a> TemporalAxis::Present => <span class="string">"#"</span>,
|
||||
<a href=#73 id=73 data-nosnippet>73</a> TemporalAxis::Past => <span class="string">"~~"</span>,
|
||||
<a href=#74 id=74 data-nosnippet>74</a> TemporalAxis::Future => <span class="string">"^^"</span>,
|
||||
<a href=#75 id=75 data-nosnippet>75</a> };
|
||||
<a href=#76 id=76 data-nosnippet>76</a> <span class="macro">write!</span>(f, <span class="string">"{}"</span>, s)
|
||||
<a href=#77 id=77 data-nosnippet>77</a> }
|
||||
<a href=#78 id=78 data-nosnippet>78</a>}
|
||||
<a href=#79 id=79 data-nosnippet>79</a>
|
||||
<a href=#80 id=80 data-nosnippet>80</a><span class="doccomment">/// Represents a parsed UCXL address.
|
||||
<a href=#81 id=81 data-nosnippet>81</a>///
|
||||
<a href=#82 id=82 data-nosnippet>82</a>/// **What**: Holds the components extracted from a UCXL URI – the agent, an
|
||||
<a href=#83 id=83 data-nosnippet>83</a>/// optional role, the project identifier, task name, temporal axis, and the
|
||||
<a href=#84 id=84 data-nosnippet>84</a>/// resource path within the project.
|
||||
<a href=#85 id=85 data-nosnippet>85</a>///
|
||||
<a href=#86 id=86 data-nosnippet>86</a>/// **How**: The struct is constructed via the `FromStr` implementation which
|
||||
<a href=#87 id=87 data-nosnippet>87</a>/// validates the scheme, splits the address into its constituent parts and
|
||||
<a href=#88 id=88 data-nosnippet>88</a>/// populates the fields. The `Display` implementation performs the inverse
|
||||
<a href=#89 id=89 data-nosnippet>89</a>/// operation.
|
||||
<a href=#90 id=90 data-nosnippet>90</a>///
|
||||
<a href=#91 id=91 data-nosnippet>91</a>/// **Why**: UCXL addresses are the primary routing mechanism inside CHORUS.
|
||||
<a href=#92 id=92 data-nosnippet>92</a>/// Encapsulating them in a dedicated type provides type‑safety and makes it
|
||||
<a href=#93 id=93 data-nosnippet>93</a>/// easy to work with address components in the rest of the codebase.
|
||||
<a href=#94 id=94 data-nosnippet>94</a></span><span class="attr">#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
<a href=#95 id=95 data-nosnippet>95</a></span><span class="kw">pub struct </span>UCXLAddress {
|
||||
<a href=#96 id=96 data-nosnippet>96</a> <span class="doccomment">/// The identifier of the agent (e.g., a user or system component).
|
||||
<a href=#97 id=97 data-nosnippet>97</a> </span><span class="kw">pub </span>agent: String,
|
||||
<a href=#98 id=98 data-nosnippet>98</a> <span class="doccomment">/// Optional role associated with the agent (e.g., "admin").
|
||||
<a href=#99 id=99 data-nosnippet>99</a> </span><span class="kw">pub </span>role: <span class="prelude-ty">Option</span><String>,
|
||||
<a href=#100 id=100 data-nosnippet>100</a> <span class="doccomment">/// The project namespace this address belongs to.
|
||||
<a href=#101 id=101 data-nosnippet>101</a> </span><span class="kw">pub </span>project: String,
|
||||
<a href=#102 id=102 data-nosnippet>102</a> <span class="doccomment">/// The specific task within the project.
|
||||
<a href=#103 id=103 data-nosnippet>103</a> </span><span class="kw">pub </span>task: String,
|
||||
<a href=#104 id=104 data-nosnippet>104</a> <span class="doccomment">/// Temporal axis indicating present, past or future.
|
||||
<a href=#105 id=105 data-nosnippet>105</a> </span><span class="kw">pub </span>temporal: TemporalAxis,
|
||||
<a href=#106 id=106 data-nosnippet>106</a> <span class="doccomment">/// Path to the resource relative to the project root.
|
||||
<a href=#107 id=107 data-nosnippet>107</a> </span><span class="kw">pub </span>path: String,
|
||||
<a href=#108 id=108 data-nosnippet>108</a>}
|
||||
<a href=#109 id=109 data-nosnippet>109</a>
|
||||
<a href=#110 id=110 data-nosnippet>110</a><span class="kw">impl </span>FromStr <span class="kw">for </span>UCXLAddress {
|
||||
<a href=#111 id=111 data-nosnippet>111</a> <span class="kw">type </span><span class="prelude-val">Err </span>= String;
|
||||
<a href=#112 id=112 data-nosnippet>112</a> <span class="doccomment">/// Parses a full UCXL address string into a `UCXLAddress` value.
|
||||
<a href=#113 id=113 data-nosnippet>113</a> ///
|
||||
<a href=#114 id=114 data-nosnippet>114</a> /// **What**: Validates the scheme (`ucxl://`), extracts the agent, optional
|
||||
<a href=#115 id=115 data-nosnippet>115</a> /// role, project, task, temporal axis and the trailing resource path.
|
||||
<a href=#116 id=116 data-nosnippet>116</a> ///
|
||||
<a href=#117 id=117 data-nosnippet>117</a> /// **How**: The implementation performs a series of `split` operations,
|
||||
<a href=#118 id=118 data-nosnippet>118</a> /// handling optional components and converting the temporal token via
|
||||
<a href=#119 id=119 data-nosnippet>119</a> /// `TemporalAxis::from_str`. Errors are surfaced as descriptive strings.
|
||||
<a href=#120 id=120 data-nosnippet>120</a> ///
|
||||
<a href=#121 id=121 data-nosnippet>121</a> /// **Why**: Centralises address parsing logic, ensuring that all parts of
|
||||
<a href=#122 id=122 data-nosnippet>122</a> /// the system interpret UCXL URIs consistently.
|
||||
<a href=#123 id=123 data-nosnippet>123</a> </span><span class="kw">fn </span>from_str(address: <span class="kw-2">&</span>str) -> <span class="prelude-ty">Result</span><<span class="self">Self</span>, <span class="self">Self</span>::Err> {
|
||||
<a href=#124 id=124 data-nosnippet>124</a> <span class="comment">// Ensure the scheme is correct
|
||||
<a href=#125 id=125 data-nosnippet>125</a> </span><span class="kw">let </span>scheme_split: Vec<<span class="kw-2">&</span>str> = address.splitn(<span class="number">2</span>, <span class="string">"://"</span>).collect();
|
||||
<a href=#126 id=126 data-nosnippet>126</a> <span class="kw">if </span>scheme_split.len() != <span class="number">2 </span>|| scheme_split[<span class="number">0</span>] != <span class="string">"ucxl" </span>{
|
||||
<a href=#127 id=127 data-nosnippet>127</a> <span class="kw">return </span><span class="prelude-val">Err</span>(<span class="string">"Address must start with 'ucxl://'"</span>.into());
|
||||
<a href=#128 id=128 data-nosnippet>128</a> }
|
||||
<a href=#129 id=129 data-nosnippet>129</a> <span class="kw">let </span>remainder = scheme_split[<span class="number">1</span>];
|
||||
<a href=#130 id=130 data-nosnippet>130</a> <span class="comment">// Split at the first '@' to separate agent/role from project/task
|
||||
<a href=#131 id=131 data-nosnippet>131</a> </span><span class="kw">let </span>parts: Vec<<span class="kw-2">&</span>str> = remainder.splitn(<span class="number">2</span>, <span class="string">'@'</span>).collect();
|
||||
<a href=#132 id=132 data-nosnippet>132</a> <span class="kw">if </span>parts.len() != <span class="number">2 </span>{
|
||||
<a href=#133 id=133 data-nosnippet>133</a> <span class="kw">return </span><span class="prelude-val">Err</span>(<span class="string">"Missing '@' separating agent and project"</span>.into());
|
||||
<a href=#134 id=134 data-nosnippet>134</a> }
|
||||
<a href=#135 id=135 data-nosnippet>135</a> <span class="comment">// Agent and optional role
|
||||
<a href=#136 id=136 data-nosnippet>136</a> </span><span class="kw">let </span>agent_part = parts[<span class="number">0</span>];
|
||||
<a href=#137 id=137 data-nosnippet>137</a> <span class="kw">let </span><span class="kw-2">mut </span>agent_iter = agent_part.splitn(<span class="number">2</span>, <span class="string">':'</span>);
|
||||
<a href=#138 id=138 data-nosnippet>138</a> <span class="kw">let </span>agent = agent_iter.next().unwrap().to_string();
|
||||
<a href=#139 id=139 data-nosnippet>139</a> <span class="kw">let </span>role = agent_iter.next().map(|s| s.to_string());
|
||||
<a href=#140 id=140 data-nosnippet>140</a> <span class="comment">// Project and task
|
||||
<a href=#141 id=141 data-nosnippet>141</a> </span><span class="kw">let </span>project_task_part = parts[<span class="number">1</span>];
|
||||
<a href=#142 id=142 data-nosnippet>142</a> <span class="comment">// Find the first '/' that starts the temporal segment and path
|
||||
<a href=#143 id=143 data-nosnippet>143</a> </span><span class="kw">let </span>slash_idx = project_task_part
|
||||
<a href=#144 id=144 data-nosnippet>144</a> .find(<span class="string">'/'</span>)
|
||||
<a href=#145 id=145 data-nosnippet>145</a> .ok_or(<span class="string">"Missing '/' before temporal segment and path"</span>)<span class="question-mark">?</span>;
|
||||
<a href=#146 id=146 data-nosnippet>146</a> <span class="kw">let </span>(proj_task, after_slash) = project_task_part.split_at(slash_idx);
|
||||
<a href=#147 id=147 data-nosnippet>147</a> <span class="kw">let </span><span class="kw-2">mut </span>proj_task_iter = proj_task.splitn(<span class="number">2</span>, <span class="string">':'</span>);
|
||||
<a href=#148 id=148 data-nosnippet>148</a> <span class="kw">let </span>project = proj_task_iter.next().ok_or(<span class="string">"Missing project"</span>)<span class="question-mark">?</span>.to_string();
|
||||
<a href=#149 id=149 data-nosnippet>149</a> <span class="kw">let </span>task = proj_task_iter.next().ok_or(<span class="string">"Missing task"</span>)<span class="question-mark">?</span>.to_string();
|
||||
<a href=#150 id=150 data-nosnippet>150</a> <span class="comment">// after_slash starts with '/', remove it
|
||||
<a href=#151 id=151 data-nosnippet>151</a> </span><span class="kw">let </span>after = <span class="kw-2">&</span>after_slash[<span class="number">1</span>..];
|
||||
<a href=#152 id=152 data-nosnippet>152</a> <span class="comment">// Temporal segment is up to the next '/' if present
|
||||
<a href=#153 id=153 data-nosnippet>153</a> </span><span class="kw">let </span>temporal_end = after
|
||||
<a href=#154 id=154 data-nosnippet>154</a> .find(<span class="string">'/'</span>)
|
||||
<a href=#155 id=155 data-nosnippet>155</a> .ok_or(<span class="string">"Missing '/' after temporal segment"</span>)<span class="question-mark">?</span>;
|
||||
<a href=#156 id=156 data-nosnippet>156</a> <span class="kw">let </span>temporal_str = <span class="kw-2">&</span>after[..temporal_end];
|
||||
<a href=#157 id=157 data-nosnippet>157</a> <span class="kw">let </span>temporal = TemporalAxis::from_str(temporal_str)<span class="question-mark">?</span>;
|
||||
<a href=#158 id=158 data-nosnippet>158</a> <span class="comment">// The rest is the resource path
|
||||
<a href=#159 id=159 data-nosnippet>159</a> </span><span class="kw">let </span>path = after[temporal_end + <span class="number">1</span>..].to_string();
|
||||
<a href=#160 id=160 data-nosnippet>160</a> <span class="prelude-val">Ok</span>(UCXLAddress {
|
||||
<a href=#161 id=161 data-nosnippet>161</a> agent,
|
||||
<a href=#162 id=162 data-nosnippet>162</a> role,
|
||||
<a href=#163 id=163 data-nosnippet>163</a> project,
|
||||
<a href=#164 id=164 data-nosnippet>164</a> task,
|
||||
<a href=#165 id=165 data-nosnippet>165</a> temporal,
|
||||
<a href=#166 id=166 data-nosnippet>166</a> path,
|
||||
<a href=#167 id=167 data-nosnippet>167</a> })
|
||||
<a href=#168 id=168 data-nosnippet>168</a> }
|
||||
<a href=#169 id=169 data-nosnippet>169</a>}
|
||||
<a href=#170 id=170 data-nosnippet>170</a>
|
||||
<a href=#171 id=171 data-nosnippet>171</a><span class="kw">impl </span>fmt::Display <span class="kw">for </span>UCXLAddress {
|
||||
<a href=#172 id=172 data-nosnippet>172</a> <span class="doccomment">/// Serialises the address back to its canonical string form.
|
||||
<a href=#173 id=173 data-nosnippet>173</a> ///
|
||||
<a href=#174 id=174 data-nosnippet>174</a> /// **What**: Constructs a `ucxl://` URI including optional role and path.
|
||||
<a href=#175 id=175 data-nosnippet>175</a> ///
|
||||
<a href=#176 id=176 data-nosnippet>176</a> /// **How**: Conditionally inserts the role component, then formats the
|
||||
<a href=#177 id=177 data-nosnippet>177</a> /// project, task, temporal token and optional path using standard `write!`
|
||||
<a href=#178 id=178 data-nosnippet>178</a> /// semantics.
|
||||
<a href=#179 id=179 data-nosnippet>179</a> ///
|
||||
<a href=#180 id=180 data-nosnippet>180</a> /// **Why**: Needed when emitting addresses (e.g., logging events or
|
||||
<a href=#181 id=181 data-nosnippet>181</a> /// generating links) so that external tools can consume them.
|
||||
<a href=#182 id=182 data-nosnippet>182</a> </span><span class="kw">fn </span>fmt(<span class="kw-2">&</span><span class="self">self</span>, f: <span class="kw-2">&mut </span>fmt::Formatter<<span class="lifetime">'_</span>>) -> fmt::Result {
|
||||
<a href=#183 id=183 data-nosnippet>183</a> <span class="kw">let </span>role_part = <span class="kw">if let </span><span class="prelude-val">Some</span>(r) = <span class="kw-2">&</span><span class="self">self</span>.role {
|
||||
<a href=#184 id=184 data-nosnippet>184</a> <span class="macro">format!</span>(<span class="string">":{}"</span>, r)
|
||||
<a href=#185 id=185 data-nosnippet>185</a> } <span class="kw">else </span>{
|
||||
<a href=#186 id=186 data-nosnippet>186</a> <span class="string">""</span>.to_string()
|
||||
<a href=#187 id=187 data-nosnippet>187</a> };
|
||||
<a href=#188 id=188 data-nosnippet>188</a> <span class="macro">write!</span>(
|
||||
<a href=#189 id=189 data-nosnippet>189</a> f,
|
||||
<a href=#190 id=190 data-nosnippet>190</a> <span class="string">"ucxl://{}{}@{}:{}/{}{}"</span>,
|
||||
<a href=#191 id=191 data-nosnippet>191</a> <span class="self">self</span>.agent,
|
||||
<a href=#192 id=192 data-nosnippet>192</a> role_part,
|
||||
<a href=#193 id=193 data-nosnippet>193</a> <span class="self">self</span>.project,
|
||||
<a href=#194 id=194 data-nosnippet>194</a> <span class="self">self</span>.task,
|
||||
<a href=#195 id=195 data-nosnippet>195</a> <span class="self">self</span>.temporal,
|
||||
<a href=#196 id=196 data-nosnippet>196</a> <span class="kw">if </span><span class="self">self</span>.path.is_empty() {
|
||||
<a href=#197 id=197 data-nosnippet>197</a> <span class="string">""</span>.to_string()
|
||||
<a href=#198 id=198 data-nosnippet>198</a> } <span class="kw">else </span>{
|
||||
<a href=#199 id=199 data-nosnippet>199</a> <span class="macro">format!</span>(<span class="string">"/{}"</span>, <span class="self">self</span>.path)
|
||||
<a href=#200 id=200 data-nosnippet>200</a> }
|
||||
<a href=#201 id=201 data-nosnippet>201</a> )
|
||||
<a href=#202 id=202 data-nosnippet>202</a> }
|
||||
<a href=#203 id=203 data-nosnippet>203</a>}
|
||||
<a href=#204 id=204 data-nosnippet>204</a>
|
||||
<a href=#205 id=205 data-nosnippet>205</a><span class="doccomment">/// Trait defining a simple key‑value metadata store.
|
||||
<a href=#206 id=206 data-nosnippet>206</a>///
|
||||
<a href=#207 id=207 data-nosnippet>207</a>/// **What**: Provides read, write and removal operations for associating a
|
||||
<a href=#208 id=208 data-nosnippet>208</a>/// string of metadata with a file‑system path.
|
||||
<a href=#209 id=209 data-nosnippet>209</a>///
|
||||
<a href=#210 id=210 data-nosnippet>210</a>/// **How**: The trait abstracts over concrete storage implementations –
|
||||
<a href=#211 id=211 data-nosnippet>211</a>/// currently an in‑memory `HashMap` – allowing callers to depend on the trait
|
||||
<a href=#212 id=212 data-nosnippet>212</a>/// rather than a specific type.
|
||||
<a href=#213 id=213 data-nosnippet>213</a>///
|
||||
<a href=#214 id=214 data-nosnippet>214</a>/// **Why**: CHORUS needs a lightweight way to attach auxiliary information to
|
||||
<a href=#215 id=215 data-nosnippet>215</a>/// files without persisting to a database; the trait makes it easy to swap in a
|
||||
<a href=#216 id=216 data-nosnippet>216</a>/// persistent backend later if required.
|
||||
<a href=#217 id=217 data-nosnippet>217</a></span><span class="kw">pub trait </span>MetadataStore {
|
||||
<a href=#218 id=218 data-nosnippet>218</a> <span class="doccomment">/// Retrieves the metadata for `path` if it exists.
|
||||
<a href=#219 id=219 data-nosnippet>219</a> </span><span class="kw">fn </span>get(<span class="kw-2">&</span><span class="self">self</span>, path: <span class="kw-2">&</span>str) -> <span class="prelude-ty">Option</span><<span class="kw-2">&</span>String>;
|
||||
<a href=#220 id=220 data-nosnippet>220</a> <span class="doccomment">/// Stores `metadata` for `path`, overwriting any existing value.
|
||||
<a href=#221 id=221 data-nosnippet>221</a> </span><span class="kw">fn </span>set(<span class="kw-2">&mut </span><span class="self">self</span>, path: <span class="kw-2">&</span>str, metadata: String);
|
||||
<a href=#222 id=222 data-nosnippet>222</a> <span class="doccomment">/// Removes the metadata entry for `path`, returning the old value if any.
|
||||
<a href=#223 id=223 data-nosnippet>223</a> </span><span class="kw">fn </span>remove(<span class="kw-2">&mut </span><span class="self">self</span>, path: <span class="kw-2">&</span>str) -> <span class="prelude-ty">Option</span><String> {
|
||||
<a href=#224 id=224 data-nosnippet>224</a> <span class="prelude-val">None
|
||||
<a href=#225 id=225 data-nosnippet>225</a> </span>}
|
||||
<a href=#226 id=226 data-nosnippet>226</a>}
|
||||
<a href=#227 id=227 data-nosnippet>227</a>
|
||||
<a href=#228 id=228 data-nosnippet>228</a><span class="doccomment">/// In‑memory implementation of `MetadataStore` backed by a `HashMap`.
|
||||
<a href=#229 id=229 data-nosnippet>229</a>///
|
||||
<a href=#230 id=230 data-nosnippet>230</a>/// **What**: Holds metadata in a hash map where the key is the file path.
|
||||
<a href=#231 id=231 data-nosnippet>231</a>///
|
||||
<a href=#232 id=232 data-nosnippet>232</a>/// **How**: Provides a `new` constructor and implements the `MetadataStore`
|
||||
<a href=#233 id=233 data-nosnippet>233</a>/// trait methods by delegating to the underlying map.
|
||||
<a href=#234 id=234 data-nosnippet>234</a>///
|
||||
<a href=#235 id=235 data-nosnippet>235</a>/// **Why**: Offers a zero‑cost, dependency‑free store suitable for unit tests
|
||||
<a href=#236 id=236 data-nosnippet>236</a>/// and simple scenarios. It can be replaced with a persistent store without
|
||||
<a href=#237 id=237 data-nosnippet>237</a>/// changing callers.
|
||||
<a href=#238 id=238 data-nosnippet>238</a></span><span class="kw">pub struct </span>InMemoryMetadataStore {
|
||||
<a href=#239 id=239 data-nosnippet>239</a> map: HashMap<String, String>,
|
||||
<a href=#240 id=240 data-nosnippet>240</a>}
|
||||
<a href=#241 id=241 data-nosnippet>241</a>
|
||||
<a href=#242 id=242 data-nosnippet>242</a><span class="kw">impl </span>InMemoryMetadataStore {
|
||||
<a href=#243 id=243 data-nosnippet>243</a> <span class="doccomment">/// Creates a fresh, empty `InMemoryMetadataStore`.
|
||||
<a href=#244 id=244 data-nosnippet>244</a> ///
|
||||
<a href=#245 id=245 data-nosnippet>245</a> /// **What**: Returns a struct with an empty internal map.
|
||||
<a href=#246 id=246 data-nosnippet>246</a> ///
|
||||
<a href=#247 id=247 data-nosnippet>247</a> /// **How**: Calls `HashMap::new`.
|
||||
<a href=#248 id=248 data-nosnippet>248</a> ///
|
||||
<a href=#249 id=249 data-nosnippet>249</a> /// **Why**: Convenience constructor for callers.
|
||||
<a href=#250 id=250 data-nosnippet>250</a> </span><span class="kw">pub fn </span>new() -> <span class="self">Self </span>{
|
||||
<a href=#251 id=251 data-nosnippet>251</a> InMemoryMetadataStore {
|
||||
<a href=#252 id=252 data-nosnippet>252</a> map: HashMap::new(),
|
||||
<a href=#253 id=253 data-nosnippet>253</a> }
|
||||
<a href=#254 id=254 data-nosnippet>254</a> }
|
||||
<a href=#255 id=255 data-nosnippet>255</a>}
|
||||
<a href=#256 id=256 data-nosnippet>256</a>
|
||||
<a href=#257 id=257 data-nosnippet>257</a><span class="kw">impl </span>MetadataStore <span class="kw">for </span>InMemoryMetadataStore {
|
||||
<a href=#258 id=258 data-nosnippet>258</a> <span class="kw">fn </span>get(<span class="kw-2">&</span><span class="self">self</span>, path: <span class="kw-2">&</span>str) -> <span class="prelude-ty">Option</span><<span class="kw-2">&</span>String> {
|
||||
<a href=#259 id=259 data-nosnippet>259</a> <span class="self">self</span>.map.get(path)
|
||||
<a href=#260 id=260 data-nosnippet>260</a> }
|
||||
<a href=#261 id=261 data-nosnippet>261</a> <span class="kw">fn </span>set(<span class="kw-2">&mut </span><span class="self">self</span>, path: <span class="kw-2">&</span>str, metadata: String) {
|
||||
<a href=#262 id=262 data-nosnippet>262</a> <span class="self">self</span>.map.insert(path.to_string(), metadata);
|
||||
<a href=#263 id=263 data-nosnippet>263</a> }
|
||||
<a href=#264 id=264 data-nosnippet>264</a> <span class="kw">fn </span>remove(<span class="kw-2">&mut </span><span class="self">self</span>, path: <span class="kw-2">&</span>str) -> <span class="prelude-ty">Option</span><String> {
|
||||
<a href=#265 id=265 data-nosnippet>265</a> <span class="self">self</span>.map.remove(path)
|
||||
<a href=#266 id=266 data-nosnippet>266</a> }
|
||||
<a href=#267 id=267 data-nosnippet>267</a>}
|
||||
<a href=#268 id=268 data-nosnippet>268</a>
|
||||
<a href=#269 id=269 data-nosnippet>269</a><span class="attr">#[cfg(test)]
|
||||
<a href=#270 id=270 data-nosnippet>270</a></span><span class="kw">mod </span>tests {
|
||||
<a href=#271 id=271 data-nosnippet>271</a> <span class="kw">use super</span>::<span class="kw-2">*</span>;
|
||||
<a href=#272 id=272 data-nosnippet>272</a>
|
||||
<a href=#273 id=273 data-nosnippet>273</a> <span class="attr">#[test]
|
||||
<a href=#274 id=274 data-nosnippet>274</a> </span><span class="kw">fn </span>test_temporal_from_str() {
|
||||
<a href=#275 id=275 data-nosnippet>275</a> <span class="macro">assert_eq!</span>(TemporalAxis::from_str(<span class="string">"#"</span>).unwrap(), TemporalAxis::Present);
|
||||
<a href=#276 id=276 data-nosnippet>276</a> <span class="macro">assert_eq!</span>(TemporalAxis::from_str(<span class="string">"~~"</span>).unwrap(), TemporalAxis::Past);
|
||||
<a href=#277 id=277 data-nosnippet>277</a> <span class="macro">assert_eq!</span>(TemporalAxis::from_str(<span class="string">"^^"</span>).unwrap(), TemporalAxis::Future);
|
||||
<a href=#278 id=278 data-nosnippet>278</a> }
|
||||
<a href=#279 id=279 data-nosnippet>279</a>
|
||||
<a href=#280 id=280 data-nosnippet>280</a> <span class="attr">#[test]
|
||||
<a href=#281 id=281 data-nosnippet>281</a> </span><span class="kw">fn </span>test_ucxl_address_parsing() {
|
||||
<a href=#282 id=282 data-nosnippet>282</a> <span class="kw">let </span>addr_str = <span class="string">"ucxl://alice:admin@myproj:task1/#/docs/readme.md"</span>;
|
||||
<a href=#283 id=283 data-nosnippet>283</a> <span class="kw">let </span>addr = UCXLAddress::from_str(addr_str).unwrap();
|
||||
<a href=#284 id=284 data-nosnippet>284</a> <span class="macro">assert_eq!</span>(addr.agent, <span class="string">"alice"</span>);
|
||||
<a href=#285 id=285 data-nosnippet>285</a> <span class="macro">assert_eq!</span>(addr.role, <span class="prelude-val">Some</span>(<span class="string">"admin"</span>.to_string()));
|
||||
<a href=#286 id=286 data-nosnippet>286</a> <span class="macro">assert_eq!</span>(addr.project, <span class="string">"myproj"</span>);
|
||||
<a href=#287 id=287 data-nosnippet>287</a> <span class="macro">assert_eq!</span>(addr.task, <span class="string">"task1"</span>);
|
||||
<a href=#288 id=288 data-nosnippet>288</a> <span class="macro">assert_eq!</span>(addr.temporal, TemporalAxis::Present);
|
||||
<a href=#289 id=289 data-nosnippet>289</a> <span class="macro">assert_eq!</span>(addr.path, <span class="string">"docs/readme.md"</span>);
|
||||
<a href=#290 id=290 data-nosnippet>290</a> <span class="macro">assert_eq!</span>(addr.to_string(), addr_str);
|
||||
<a href=#291 id=291 data-nosnippet>291</a> }
|
||||
<a href=#292 id=292 data-nosnippet>292</a>
|
||||
<a href=#293 id=293 data-nosnippet>293</a> <span class="attr">#[test]
|
||||
<a href=#294 id=294 data-nosnippet>294</a> </span><span class="kw">fn </span>test_metadata_store() {
|
||||
<a href=#295 id=295 data-nosnippet>295</a> <span class="kw">let </span><span class="kw-2">mut </span>store = InMemoryMetadataStore::new();
|
||||
<a href=#296 id=296 data-nosnippet>296</a> store.set(<span class="string">"/foo.txt"</span>, <span class="string">"meta"</span>.into());
|
||||
<a href=#297 id=297 data-nosnippet>297</a> <span class="macro">assert_eq!</span>(store.get(<span class="string">"/foo.txt"</span>), <span class="prelude-val">Some</span>(<span class="kw-2">&</span><span class="string">"meta"</span>.to_string()));
|
||||
<a href=#298 id=298 data-nosnippet>298</a> store.remove(<span class="string">"/foo.txt"</span>);
|
||||
<a href=#299 id=299 data-nosnippet>299</a> <span class="macro">assert!</span>(store.get(<span class="string">"/foo.txt"</span>).is_none());
|
||||
<a href=#300 id=300 data-nosnippet>300</a> }
|
||||
<a href=#301 id=301 data-nosnippet>301</a>}</code></pre></div></section></main></body></html>
|
||||
91
target/doc/src/ucxl/watcher.rs.html
Normal file
91
target/doc/src/ucxl/watcher.rs.html
Normal file
@@ -0,0 +1,91 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `UCXL/src/watcher.rs`."><title>watcher.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-916cea96.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="ucxl" data-themes="" data-resource-suffix="" data-rustdoc-version="1.87.0 (17067e9ac 2025-05-09)" data-channel="1.87.0" data-search-js="search-e7298875.js" data-settings-js="settings-d72f25bb.js" ><script src="../../static.files/storage-82c7156e.js"></script><script defer src="../../static.files/src-script-63605ae7.js"></script><script defer src="../../src-files.js"></script><script defer src="../../static.files/main-fb8c74a8.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer"></div><main><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1><div class="sub-heading">ucxl/</div>watcher.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-2"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="doccomment">//! UCXL filesystem watcher.
|
||||
<a href=#2 id=2 data-nosnippet>2</a>//!
|
||||
<a href=#3 id=3 data-nosnippet>3</a>//! This module provides a thin wrapper around the `notify` crate to watch a
|
||||
<a href=#4 id=4 data-nosnippet>4</a>//! directory (or "project") for filesystem events. When a change is detected,
|
||||
<a href=#5 id=5 data-nosnippet>5</a>//! the watcher attempts to construct a corresponding `UCXLAddress` using a
|
||||
<a href=#6 id=6 data-nosnippet>6</a>//! simple heuristic and logs the event. This is primarily used by CHORUS for
|
||||
<a href=#7 id=7 data-nosnippet>7</a>//! reactive workflows such as automatically updating metadata when files are
|
||||
<a href=#8 id=8 data-nosnippet>8</a>//! added, modified or removed.
|
||||
<a href=#9 id=9 data-nosnippet>9</a>
|
||||
<a href=#10 id=10 data-nosnippet>10</a></span><span class="kw">use </span>notify::{Config, RecommendedWatcher, RecursiveMode, Watcher};
|
||||
<a href=#11 id=11 data-nosnippet>11</a><span class="kw">use </span>std::path::Path;
|
||||
<a href=#12 id=12 data-nosnippet>12</a><span class="kw">use </span>std::sync::mpsc::channel;
|
||||
<a href=#13 id=13 data-nosnippet>13</a><span class="kw">use </span><span class="kw">crate</span>::UCXLAddress;
|
||||
<a href=#14 id=14 data-nosnippet>14</a><span class="kw">use </span>std::str::FromStr;
|
||||
<a href=#15 id=15 data-nosnippet>15</a>
|
||||
<a href=#16 id=16 data-nosnippet>16</a><span class="doccomment">/// Represents a watcher rooted at a specific base path.
|
||||
<a href=#17 id=17 data-nosnippet>17</a>///
|
||||
<a href=#18 id=18 data-nosnippet>18</a>/// **What**: Holds the absolute path that the watcher monitors.
|
||||
<a href=#19 id=19 data-nosnippet>19</a>///
|
||||
<a href=#20 id=20 data-nosnippet>20</a>/// **How**: The path is stored as a `PathBuf`. The watcher is created via the
|
||||
<a href=#21 id=21 data-nosnippet>21</a>/// `new` constructor which accepts any type that can be referenced as a `Path`.
|
||||
<a href=#22 id=22 data-nosnippet>22</a>/// The underlying `notify::RecommendedWatcher` is configured with the default
|
||||
<a href=#23 id=23 data-nosnippet>23</a>/// `Config` and set to watch recursively.
|
||||
<a href=#24 id=24 data-nosnippet>24</a>///
|
||||
<a href=#25 id=25 data-nosnippet>25</a>/// **Why**: Encapsulating the watcher logic in a dedicated struct makes it easy
|
||||
<a href=#26 id=26 data-nosnippet>26</a>/// to instantiate multiple independent watchers and keeps the public API tidy.
|
||||
<a href=#27 id=27 data-nosnippet>27</a></span><span class="kw">pub struct </span>UCXLWatcher {
|
||||
<a href=#28 id=28 data-nosnippet>28</a> base_path: std::path::PathBuf,
|
||||
<a href=#29 id=29 data-nosnippet>29</a>}
|
||||
<a href=#30 id=30 data-nosnippet>30</a>
|
||||
<a href=#31 id=31 data-nosnippet>31</a><span class="kw">impl </span>UCXLWatcher {
|
||||
<a href=#32 id=32 data-nosnippet>32</a> <span class="doccomment">/// Creates a new `UCXLWatcher` for the given path.
|
||||
<a href=#33 id=33 data-nosnippet>33</a> ///
|
||||
<a href=#34 id=34 data-nosnippet>34</a> /// **What**: Accepts any generic `AsRef<Path>` so callers can pass a `&str`,
|
||||
<a href=#35 id=35 data-nosnippet>35</a> /// `Path`, or `PathBuf`.
|
||||
<a href=#36 id=36 data-nosnippet>36</a> ///
|
||||
<a href=#37 id=37 data-nosnippet>37</a> /// **How**: The provided path is converted to a `PathBuf` and stored.
|
||||
<a href=#38 id=38 data-nosnippet>38</a> ///
|
||||
<a href=#39 id=39 data-nosnippet>39</a> /// **Why**: Convenience constructor used throughout CHORUS when a watcher is
|
||||
<a href=#40 id=40 data-nosnippet>40</a> /// needed for a project directory.
|
||||
<a href=#41 id=41 data-nosnippet>41</a> </span><span class="kw">pub fn </span>new<P: AsRef<Path>>(path: P) -> <span class="self">Self </span>{
|
||||
<a href=#42 id=42 data-nosnippet>42</a> <span class="self">Self </span>{
|
||||
<a href=#43 id=43 data-nosnippet>43</a> base_path: path.as_ref().to_path_buf(),
|
||||
<a href=#44 id=44 data-nosnippet>44</a> }
|
||||
<a href=#45 id=45 data-nosnippet>45</a> }
|
||||
<a href=#46 id=46 data-nosnippet>46</a>
|
||||
<a href=#47 id=47 data-nosnippet>47</a> <span class="doccomment">/// Starts the watch loop, blocking indefinitely while handling events.
|
||||
<a href=#48 id=48 data-nosnippet>48</a> ///
|
||||
<a href=#49 id=49 data-nosnippet>49</a> /// **What**: Sets up a channel, creates a `RecommendedWatcher`, and begins
|
||||
<a href=#50 id=50 data-nosnippet>50</a> /// watching the `base_path` recursively. For each incoming event, it
|
||||
<a href=#51 id=51 data-nosnippet>51</a> /// attempts to map the filesystem path to a UCXL address and prints a log.
|
||||
<a href=#52 id=52 data-nosnippet>52</a> ///
|
||||
<a href=#53 id=53 data-nosnippet>53</a> /// **How**: Uses the `notify` crate's event API. The heuristic address
|
||||
<a href=#54 id=54 data-nosnippet>54</a> /// format is `ucxl://system:watcher@local:filesystem/#/<relative_path>`.
|
||||
<a href=#55 id=55 data-nosnippet>55</a> /// It parses this string with `UCXLAddress::from_str` and logs the result.
|
||||
<a href=#56 id=56 data-nosnippet>56</a> /// Errors from parsing are ignored (they simply aren't printed).
|
||||
<a href=#57 id=57 data-nosnippet>57</a> ///
|
||||
<a href=#58 id=58 data-nosnippet>58</a> /// **Why**: Provides a simple, observable bridge between raw filesystem
|
||||
<a href=#59 id=59 data-nosnippet>59</a> /// changes and the UCXL addressing scheme, allowing other components to react
|
||||
<a href=#60 id=60 data-nosnippet>60</a> /// to changes using a uniform identifier.
|
||||
<a href=#61 id=61 data-nosnippet>61</a> </span><span class="kw">pub fn </span>watch_loop(<span class="kw-2">&</span><span class="self">self</span>) -> <span class="prelude-ty">Result</span><(), Box<<span class="kw">dyn </span>std::error::Error>> {
|
||||
<a href=#62 id=62 data-nosnippet>62</a> <span class="kw">let </span>(tx, rx) = channel();
|
||||
<a href=#63 id=63 data-nosnippet>63</a>
|
||||
<a href=#64 id=64 data-nosnippet>64</a> <span class="kw">let </span><span class="kw-2">mut </span>watcher = RecommendedWatcher::new(tx, Config::default())<span class="question-mark">?</span>;
|
||||
<a href=#65 id=65 data-nosnippet>65</a> watcher.watch(<span class="kw-2">&</span><span class="self">self</span>.base_path, RecursiveMode::Recursive)<span class="question-mark">?</span>;
|
||||
<a href=#66 id=66 data-nosnippet>66</a>
|
||||
<a href=#67 id=67 data-nosnippet>67</a> <span class="macro">println!</span>(<span class="string">"UCXL Watcher started on {:?}"</span>, <span class="self">self</span>.base_path);
|
||||
<a href=#68 id=68 data-nosnippet>68</a>
|
||||
<a href=#69 id=69 data-nosnippet>69</a> <span class="kw">for </span>res <span class="kw">in </span>rx {
|
||||
<a href=#70 id=70 data-nosnippet>70</a> <span class="kw">match </span>res {
|
||||
<a href=#71 id=71 data-nosnippet>71</a> <span class="prelude-val">Ok</span>(event) => {
|
||||
<a href=#72 id=72 data-nosnippet>72</a> <span class="kw">for </span>path <span class="kw">in </span>event.paths {
|
||||
<a href=#73 id=73 data-nosnippet>73</a> <span class="kw">if let </span><span class="prelude-val">Some</span>(rel_path) = path.strip_prefix(<span class="kw-2">&</span><span class="self">self</span>.base_path).ok() {
|
||||
<a href=#74 id=74 data-nosnippet>74</a> <span class="kw">let </span>rel_str = rel_path.to_string_lossy();
|
||||
<a href=#75 id=75 data-nosnippet>75</a> <span class="comment">// Heuristic address mapping: ucxl://system:watcher@local:filesystem/#/path
|
||||
<a href=#76 id=76 data-nosnippet>76</a> </span><span class="kw">let </span>addr_str = <span class="macro">format!</span>(
|
||||
<a href=#77 id=77 data-nosnippet>77</a> <span class="string">"ucxl://system:watcher@local:filesystem/#/{}"</span>,
|
||||
<a href=#78 id=78 data-nosnippet>78</a> rel_str
|
||||
<a href=#79 id=79 data-nosnippet>79</a> );
|
||||
<a href=#80 id=80 data-nosnippet>80</a> <span class="kw">if let </span><span class="prelude-val">Ok</span>(addr) = UCXLAddress::from_str(<span class="kw-2">&</span>addr_str) {
|
||||
<a href=#81 id=81 data-nosnippet>81</a> <span class="macro">println!</span>(<span class="string">"[UCXL EVENT] {:?} -> {}"</span>, event.kind, addr);
|
||||
<a href=#82 id=82 data-nosnippet>82</a> }
|
||||
<a href=#83 id=83 data-nosnippet>83</a> }
|
||||
<a href=#84 id=84 data-nosnippet>84</a> }
|
||||
<a href=#85 id=85 data-nosnippet>85</a> }
|
||||
<a href=#86 id=86 data-nosnippet>86</a> <span class="prelude-val">Err</span>(e) => <span class="macro">println!</span>(<span class="string">"watch error: {:?}"</span>, e),
|
||||
<a href=#87 id=87 data-nosnippet>87</a> }
|
||||
<a href=#88 id=88 data-nosnippet>88</a> }
|
||||
<a href=#89 id=89 data-nosnippet>89</a> <span class="prelude-val">Ok</span>(())
|
||||
<a href=#90 id=90 data-nosnippet>90</a> }
|
||||
<a href=#91 id=91 data-nosnippet>91</a>}</code></pre></div></section></main></body></html>
|
||||
71
target/doc/static.files/COPYRIGHT-7fb11f4e.txt
Normal file
71
target/doc/static.files/COPYRIGHT-7fb11f4e.txt
Normal file
@@ -0,0 +1,71 @@
|
||||
# REUSE-IgnoreStart
|
||||
|
||||
These documentation pages include resources by third parties. This copyright
|
||||
file applies only to those resources. The following third party resources are
|
||||
included, and carry their own copyright notices and license terms:
|
||||
|
||||
* Fira Sans (FiraSans-Regular.woff2, FiraSans-Medium.woff2):
|
||||
|
||||
Copyright (c) 2014, Mozilla Foundation https://mozilla.org/
|
||||
with Reserved Font Name Fira Sans.
|
||||
|
||||
Copyright (c) 2014, Telefonica S.A.
|
||||
|
||||
Licensed under the SIL Open Font License, Version 1.1.
|
||||
See FiraSans-LICENSE.txt.
|
||||
|
||||
* rustdoc.css, main.js, and playpen.js:
|
||||
|
||||
Copyright 2015 The Rust Developers.
|
||||
Licensed under the Apache License, Version 2.0 (see LICENSE-APACHE.txt) or
|
||||
the MIT license (LICENSE-MIT.txt) at your option.
|
||||
|
||||
* normalize.css:
|
||||
|
||||
Copyright (c) Nicolas Gallagher and Jonathan Neal.
|
||||
Licensed under the MIT license (see LICENSE-MIT.txt).
|
||||
|
||||
* Source Code Pro (SourceCodePro-Regular.ttf.woff2,
|
||||
SourceCodePro-Semibold.ttf.woff2, SourceCodePro-It.ttf.woff2):
|
||||
|
||||
Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/),
|
||||
with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark
|
||||
of Adobe Systems Incorporated in the United States and/or other countries.
|
||||
|
||||
Licensed under the SIL Open Font License, Version 1.1.
|
||||
See SourceCodePro-LICENSE.txt.
|
||||
|
||||
* Source Serif 4 (SourceSerif4-Regular.ttf.woff2, SourceSerif4-Bold.ttf.woff2,
|
||||
SourceSerif4-It.ttf.woff2, SourceSerif4-Semibold.ttf.woff2):
|
||||
|
||||
Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name
|
||||
'Source'. All Rights Reserved. Source is a trademark of Adobe in the United
|
||||
States and/or other countries.
|
||||
|
||||
Licensed under the SIL Open Font License, Version 1.1.
|
||||
See SourceSerif4-LICENSE.md.
|
||||
|
||||
* Nanum Barun Gothic Font (NanumBarunGothic.woff2)
|
||||
|
||||
Copyright 2010, NAVER Corporation (http://www.nhncorp.com)
|
||||
with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver NanumGothic,
|
||||
NanumMyeongjo, Naver NanumMyeongjo, NanumBrush, Naver NanumBrush, NanumPen,
|
||||
Naver NanumPen, Naver NanumGothicEco, NanumGothicEco,
|
||||
Naver NanumMyeongjoEco, NanumMyeongjoEco, Naver NanumGothicLight,
|
||||
NanumGothicLight, NanumBarunGothic, Naver NanumBarunGothic.
|
||||
|
||||
https://hangeul.naver.com/2017/nanum
|
||||
https://github.com/hiun/NanumBarunGothic
|
||||
|
||||
Licensed under the SIL Open Font License, Version 1.1.
|
||||
See NanumBarunGothic-LICENSE.txt.
|
||||
|
||||
* Rust logos (rust-logo.svg, favicon.svg, favicon-32x32.png)
|
||||
|
||||
Copyright 2025 Rust Foundation.
|
||||
Licensed under the Creative Commons Attribution license (CC-BY).
|
||||
https://rustfoundation.org/policy/rust-trademark-policy/
|
||||
|
||||
This copyright file is intended to be distributed with rustdoc output.
|
||||
|
||||
# REUSE-IgnoreEnd
|
||||
BIN
target/doc/static.files/FiraMono-Medium-86f75c8c.woff2
Normal file
BIN
target/doc/static.files/FiraMono-Medium-86f75c8c.woff2
Normal file
Binary file not shown.
BIN
target/doc/static.files/FiraMono-Regular-87c26294.woff2
Normal file
BIN
target/doc/static.files/FiraMono-Regular-87c26294.woff2
Normal file
Binary file not shown.
BIN
target/doc/static.files/FiraSans-Italic-81dc35de.woff2
Normal file
BIN
target/doc/static.files/FiraSans-Italic-81dc35de.woff2
Normal file
Binary file not shown.
98
target/doc/static.files/FiraSans-LICENSE-05ab6dbd.txt
Normal file
98
target/doc/static.files/FiraSans-LICENSE-05ab6dbd.txt
Normal file
@@ -0,0 +1,98 @@
|
||||
// REUSE-IgnoreStart
|
||||
|
||||
Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A.
|
||||
with Reserved Font Name < Fira >,
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
||||
// REUSE-IgnoreEnd
|
||||
BIN
target/doc/static.files/FiraSans-Medium-e1aa3f0a.woff2
Normal file
BIN
target/doc/static.files/FiraSans-Medium-e1aa3f0a.woff2
Normal file
Binary file not shown.
BIN
target/doc/static.files/FiraSans-MediumItalic-ccf7e434.woff2
Normal file
BIN
target/doc/static.files/FiraSans-MediumItalic-ccf7e434.woff2
Normal file
Binary file not shown.
BIN
target/doc/static.files/FiraSans-Regular-0fe48ade.woff2
Normal file
BIN
target/doc/static.files/FiraSans-Regular-0fe48ade.woff2
Normal file
Binary file not shown.
201
target/doc/static.files/LICENSE-APACHE-a60eea81.txt
Normal file
201
target/doc/static.files/LICENSE-APACHE-a60eea81.txt
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
23
target/doc/static.files/LICENSE-MIT-23f18e03.txt
Normal file
23
target/doc/static.files/LICENSE-MIT-23f18e03.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
BIN
target/doc/static.files/NanumBarunGothic-13b3dcba.ttf.woff2
Normal file
BIN
target/doc/static.files/NanumBarunGothic-13b3dcba.ttf.woff2
Normal file
Binary file not shown.
103
target/doc/static.files/NanumBarunGothic-LICENSE-a37d393b.txt
Normal file
103
target/doc/static.files/NanumBarunGothic-LICENSE-a37d393b.txt
Normal file
@@ -0,0 +1,103 @@
|
||||
// REUSE-IgnoreStart
|
||||
|
||||
Copyright (c) 2010, NAVER Corporation (https://www.navercorp.com/),
|
||||
|
||||
with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver NanumGothic,
|
||||
NanumMyeongjo, Naver NanumMyeongjo, NanumBrush, Naver NanumBrush, NanumPen,
|
||||
Naver NanumPen, Naver NanumGothicEco, NanumGothicEco, Naver NanumMyeongjoEco,
|
||||
NanumMyeongjoEco, Naver NanumGothicLight, NanumGothicLight, NanumBarunGothic,
|
||||
Naver NanumBarunGothic, NanumSquareRound, NanumBarunPen, MaruBuri
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
||||
// REUSE-IgnoreEnd
|
||||
BIN
target/doc/static.files/SourceCodePro-It-fc8b9304.ttf.woff2
Normal file
BIN
target/doc/static.files/SourceCodePro-It-fc8b9304.ttf.woff2
Normal file
Binary file not shown.
97
target/doc/static.files/SourceCodePro-LICENSE-67f54ca7.txt
Normal file
97
target/doc/static.files/SourceCodePro-LICENSE-67f54ca7.txt
Normal file
@@ -0,0 +1,97 @@
|
||||
// REUSE-IgnoreStart
|
||||
|
||||
Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
|
||||
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
||||
// REUSE-IgnoreEnd
|
||||
BIN
target/doc/static.files/SourceCodePro-Regular-8badfe75.ttf.woff2
Normal file
BIN
target/doc/static.files/SourceCodePro-Regular-8badfe75.ttf.woff2
Normal file
Binary file not shown.
Binary file not shown.
BIN
target/doc/static.files/SourceSerif4-Bold-6d4fd4c0.ttf.woff2
Normal file
BIN
target/doc/static.files/SourceSerif4-Bold-6d4fd4c0.ttf.woff2
Normal file
Binary file not shown.
BIN
target/doc/static.files/SourceSerif4-It-ca3b17ed.ttf.woff2
Normal file
BIN
target/doc/static.files/SourceSerif4-It-ca3b17ed.ttf.woff2
Normal file
Binary file not shown.
98
target/doc/static.files/SourceSerif4-LICENSE-a2cfd9d5.md
Normal file
98
target/doc/static.files/SourceSerif4-LICENSE-a2cfd9d5.md
Normal file
@@ -0,0 +1,98 @@
|
||||
<!-- REUSE-IgnoreStart -->
|
||||
|
||||
Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries.
|
||||
Copyright 2014 - 2023 Adobe (http://www.adobe.com/), with Reserved Font Name ‘Source’. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
|
||||
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
||||
<!-- REUSE-IgnoreEnd -->
|
||||
BIN
target/doc/static.files/SourceSerif4-Regular-6b053e98.ttf.woff2
Normal file
BIN
target/doc/static.files/SourceSerif4-Regular-6b053e98.ttf.woff2
Normal file
Binary file not shown.
BIN
target/doc/static.files/SourceSerif4-Semibold-457a13ac.ttf.woff2
Normal file
BIN
target/doc/static.files/SourceSerif4-Semibold-457a13ac.ttf.woff2
Normal file
Binary file not shown.
24
target/doc/static.files/favicon-044be391.svg
Normal file
24
target/doc/static.files/favicon-044be391.svg
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;">
|
||||
<defs>
|
||||
<style type="text/css"><![CDATA[
|
||||
#logo {
|
||||
fill-rule: nonzero;
|
||||
}
|
||||
#logo-teeth {
|
||||
stroke: #000000;
|
||||
stroke-width: 0.92px;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
#logo {
|
||||
fill: #FFFFFF;
|
||||
fill-rule: nonzero;
|
||||
}
|
||||
#logo-teeth {
|
||||
fill: #FFFFFF;
|
||||
stroke: #FFFFFF;
|
||||
stroke-width: 0.92px;
|
||||
}
|
||||
}
|
||||
]]></style>
|
||||
</defs>
|
||||
<path id="logo" d="M15.993,1.54c-7.972,0 -14.461,6.492 -14.461,14.462c0,7.969 6.492,14.461 14.461,14.461c7.97,0 14.462,-6.492 14.462,-14.461c0,-7.97 -6.492,-14.462 -14.462,-14.462Zm-0.021,1.285c0.511,0.013 0.924,0.439 0.924,0.951c0,0.522 -0.43,0.952 -0.952,0.952c-0.522,0 -0.951,-0.43 -0.951,-0.952c0,0 0,0 0,0c0,-0.522 0.429,-0.952 0.951,-0.952c0.01,0 0.019,0.001 0.028,0.001Zm2.178,1.566c3.379,0.633 6.313,2.723 8.016,5.709l-1.123,2.533c-0.193,0.438 0.006,0.952 0.44,1.147l2.16,0.958c0.067,0.675 0.076,1.355 0.025,2.031l-1.202,0c-0.12,0 -0.169,0.08 -0.169,0.196l0,0.551c0,1.297 -0.731,1.582 -1.373,1.652c-0.612,0.07 -1.288,-0.257 -1.374,-0.63c-0.361,-2.029 -0.961,-2.46 -1.909,-3.21c1.178,-0.746 2.401,-1.85 2.401,-3.325c0,-1.594 -1.092,-2.597 -1.835,-3.09c-1.046,-0.688 -2.203,-0.826 -2.515,-0.826l-12.421,0c1.717,-1.918 4.02,-3.218 6.55,-3.696l1.466,1.536c0.33,0.346 0.878,0.361 1.223,0.028l1.64,-1.564Zm-13.522,7.043c0.511,0.015 0.924,0.44 0.924,0.951c0,0.522 -0.43,0.952 -0.952,0.952c-0.522,0 -0.951,-0.43 -0.951,-0.952c0,0 0,0 0,0c0,-0.522 0.429,-0.951 0.951,-0.951c0.009,0 0.019,0 0.028,0Zm22.685,0.043c0.511,0.015 0.924,0.44 0.924,0.951c0,0.522 -0.43,0.952 -0.952,0.952c-0.522,0 -0.951,-0.43 -0.951,-0.952c0,0 0,0 0,0c0,-0.522 0.429,-0.952 0.951,-0.952c0.01,0 0.019,0 0.028,0.001Zm-20.892,0.153l1.658,0l0,7.477l-3.347,0c-0.414,-1.452 -0.542,-2.97 -0.38,-4.47l2.05,-0.912c0.438,-0.195 0.637,-0.706 0.441,-1.144l-0.422,-0.951Zm6.92,0.079l3.949,0c0.205,0 1.441,0.236 1.441,1.163c0,0.768 -0.948,1.043 -1.728,1.043l-3.665,0l0.003,-2.206Zm0,5.373l3.026,0c0.275,0 1.477,0.079 1.86,1.615c0.119,0.471 0.385,2.007 0.566,2.499c0.18,0.551 0.911,1.652 1.691,1.652l4.938,0c-0.331,0.444 -0.693,0.863 -1.083,1.255l-2.01,-0.432c-0.468,-0.101 -0.93,0.199 -1.031,0.667l-0.477,2.228c-3.104,1.406 -6.672,1.389 -9.762,-0.046l-0.478,-2.228c-0.101,-0.468 -0.56,-0.767 -1.028,-0.667l-1.967,0.423c-0.365,-0.377 -0.704,-0.778 -1.016,-1.2l9.567,0c0.107,0 0.181,-0.018 0.181,-0.119l0,-3.384c0,-0.097 -0.074,-0.119 -0.181,-0.119l-2.799,0l0.003,-2.144Zm-4.415,7.749c0.512,0.015 0.924,0.44 0.924,0.951c0,0.522 -0.429,0.952 -0.951,0.952c-0.522,0 -0.952,-0.43 -0.952,-0.952c0,0 0,0 0,0c0,-0.522 0.43,-0.952 0.952,-0.952c0.009,0 0.018,0.001 0.027,0.001Zm14.089,0.043c0.511,0.015 0.924,0.439 0.923,0.951c0,0.522 -0.429,0.952 -0.951,0.952c-0.522,0 -0.951,-0.43 -0.951,-0.952c0,0 0,0 0,0c0,-0.522 0.429,-0.952 0.951,-0.952c0.009,0 0.018,0 0.028,0.001Z"/><path id="logo-teeth" d="M29.647,16.002c0,7.49 -6.163,13.653 -13.654,13.653c-7.49,0 -13.654,-6.163 -13.654,-13.653c0,-7.491 6.164,-13.654 13.654,-13.654c7.491,0 13.654,6.163 13.654,13.654Zm-0.257,-1.319l2.13,1.319l-2.13,1.318l1.83,1.71l-2.344,0.878l1.463,2.035l-2.475,0.404l1.04,2.282l-2.506,-0.089l0.575,2.442l-2.441,-0.576l0.089,2.506l-2.283,-1.04l-0.403,2.475l-2.035,-1.462l-0.878,2.343l-1.71,-1.829l-1.319,2.129l-1.318,-2.129l-1.71,1.829l-0.878,-2.343l-2.035,1.462l-0.404,-2.475l-2.282,1.04l0.089,-2.506l-2.442,0.576l0.575,-2.442l-2.505,0.089l1.04,-2.282l-2.475,-0.404l1.462,-2.035l-2.343,-0.878l1.829,-1.71l-2.129,-1.318l2.129,-1.319l-1.829,-1.71l2.343,-0.878l-1.462,-2.035l2.475,-0.404l-1.04,-2.282l2.505,0.089l-0.575,-2.441l2.442,0.575l-0.089,-2.506l2.282,1.04l0.404,-2.475l2.035,1.463l0.878,-2.344l1.71,1.83l1.318,-2.13l1.319,2.13l1.71,-1.83l0.878,2.344l2.035,-1.463l0.403,2.475l2.283,-1.04l-0.089,2.506l2.441,-0.575l-0.575,2.441l2.506,-0.089l-1.04,2.282l2.475,0.404l-1.463,2.035l2.344,0.878l-1.83,1.71Z"/></svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
BIN
target/doc/static.files/favicon-32x32-6580c154.png
Normal file
BIN
target/doc/static.files/favicon-32x32-6580c154.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
11
target/doc/static.files/main-fb8c74a8.js
Normal file
11
target/doc/static.files/main-fb8c74a8.js
Normal file
File diff suppressed because one or more lines are too long
2
target/doc/static.files/normalize-9960930a.css
Normal file
2
target/doc/static.files/normalize-9960930a.css
Normal file
@@ -0,0 +1,2 @@
|
||||
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
|
||||
html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type="button"],[type="reset"],[type="submit"],button{-webkit-appearance:button}[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}
|
||||
1
target/doc/static.files/noscript-893ab5e7.css
Normal file
1
target/doc/static.files/noscript-893ab5e7.css
Normal file
File diff suppressed because one or more lines are too long
61
target/doc/static.files/rust-logo-9a9549ea.svg
Normal file
61
target/doc/static.files/rust-logo-9a9549ea.svg
Normal file
@@ -0,0 +1,61 @@
|
||||
<svg version="1.1" height="106" width="106" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="logo" transform="translate(53, 53)">
|
||||
<path id="r" transform="translate(0.5, 0.5)" stroke="black" stroke-width="1" stroke-linejoin="round" d="
|
||||
M -9,-15 H 4 C 12,-15 12,-7 4,-7 H -9 Z
|
||||
M -40,22 H 0 V 11 H -9 V 3 H 1 C 12,3 6,22 15,22 H 40
|
||||
V 3 H 34 V 5 C 34,13 25,12 24,7 C 23,2 19,-2 18,-2 C 33,-10 24,-26 12,-26 H -35
|
||||
V -15 H -25 V 11 H -40 Z" />
|
||||
<g id="gear" mask="url(#holes)">
|
||||
<circle r="43" fill="none" stroke="black" stroke-width="9" />
|
||||
<g id="cogs">
|
||||
<polygon id="cog" stroke="black" stroke-width="3" stroke-linejoin="round" points="46,3 51,0 46,-3" />
|
||||
<use xlink:href="#cog" transform="rotate(11.25)" />
|
||||
<use xlink:href="#cog" transform="rotate(22.50)" />
|
||||
<use xlink:href="#cog" transform="rotate(33.75)" />
|
||||
<use xlink:href="#cog" transform="rotate(45.00)" />
|
||||
<use xlink:href="#cog" transform="rotate(56.25)" />
|
||||
<use xlink:href="#cog" transform="rotate(67.50)" />
|
||||
<use xlink:href="#cog" transform="rotate(78.75)" />
|
||||
<use xlink:href="#cog" transform="rotate(90.00)" />
|
||||
<use xlink:href="#cog" transform="rotate(101.25)" />
|
||||
<use xlink:href="#cog" transform="rotate(112.50)" />
|
||||
<use xlink:href="#cog" transform="rotate(123.75)" />
|
||||
<use xlink:href="#cog" transform="rotate(135.00)" />
|
||||
<use xlink:href="#cog" transform="rotate(146.25)" />
|
||||
<use xlink:href="#cog" transform="rotate(157.50)" />
|
||||
<use xlink:href="#cog" transform="rotate(168.75)" />
|
||||
<use xlink:href="#cog" transform="rotate(180.00)" />
|
||||
<use xlink:href="#cog" transform="rotate(191.25)" />
|
||||
<use xlink:href="#cog" transform="rotate(202.50)" />
|
||||
<use xlink:href="#cog" transform="rotate(213.75)" />
|
||||
<use xlink:href="#cog" transform="rotate(225.00)" />
|
||||
<use xlink:href="#cog" transform="rotate(236.25)" />
|
||||
<use xlink:href="#cog" transform="rotate(247.50)" />
|
||||
<use xlink:href="#cog" transform="rotate(258.75)" />
|
||||
<use xlink:href="#cog" transform="rotate(270.00)" />
|
||||
<use xlink:href="#cog" transform="rotate(281.25)" />
|
||||
<use xlink:href="#cog" transform="rotate(292.50)" />
|
||||
<use xlink:href="#cog" transform="rotate(303.75)" />
|
||||
<use xlink:href="#cog" transform="rotate(315.00)" />
|
||||
<use xlink:href="#cog" transform="rotate(326.25)" />
|
||||
<use xlink:href="#cog" transform="rotate(337.50)" />
|
||||
<use xlink:href="#cog" transform="rotate(348.75)" />
|
||||
</g>
|
||||
<g id="mounts">
|
||||
<polygon id="mount" stroke="black" stroke-width="6" stroke-linejoin="round" points="-7,-42 0,-35 7,-42" />
|
||||
<use xlink:href="#mount" transform="rotate(72)" />
|
||||
<use xlink:href="#mount" transform="rotate(144)" />
|
||||
<use xlink:href="#mount" transform="rotate(216)" />
|
||||
<use xlink:href="#mount" transform="rotate(288)" />
|
||||
</g>
|
||||
</g>
|
||||
<mask id="holes">
|
||||
<rect x="-60" y="-60" width="120" height="120" fill="white"/>
|
||||
<circle id="hole" cy="-40" r="3" />
|
||||
<use xlink:href="#hole" transform="rotate(72)" />
|
||||
<use xlink:href="#hole" transform="rotate(144)" />
|
||||
<use xlink:href="#hole" transform="rotate(216)" />
|
||||
<use xlink:href="#hole" transform="rotate(288)" />
|
||||
</mask>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
63
target/doc/static.files/rustdoc-916cea96.css
Normal file
63
target/doc/static.files/rustdoc-916cea96.css
Normal file
File diff suppressed because one or more lines are too long
1
target/doc/static.files/scrape-examples-5e967b76.js
Normal file
1
target/doc/static.files/scrape-examples-5e967b76.js
Normal file
@@ -0,0 +1 @@
|
||||
"use strict";(function(){const DEFAULT_MAX_LINES=5;const HIDDEN_MAX_LINES=10;function scrollToLoc(elt,loc,isHidden){const lines=elt.querySelectorAll("[data-nosnippet]");let scrollOffset;const maxLines=isHidden?HIDDEN_MAX_LINES:DEFAULT_MAX_LINES;if(loc[1]-loc[0]>maxLines){const line=Math.max(0,loc[0]-1);scrollOffset=lines[line].offsetTop}else{const halfHeight=elt.offsetHeight/2;const offsetTop=lines[loc[0]].offsetTop;const lastLine=lines[loc[1]];const offsetBot=lastLine.offsetTop+lastLine.offsetHeight;const offsetMid=(offsetTop+offsetBot)/2;scrollOffset=offsetMid-halfHeight}lines[0].parentElement.scrollTo(0,scrollOffset);elt.querySelector(".rust").scrollTo(0,scrollOffset)}function createScrapeButton(parent,className,content){const button=document.createElement("button");button.className=className;button.title=content;parent.insertBefore(button,parent.firstChild);return button}window.updateScrapedExample=(example,buttonHolder)=>{let locIndex=0;const highlights=Array.prototype.slice.call(example.querySelectorAll(".highlight"));const link=example.querySelector(".scraped-example-title a");let expandButton=null;if(!example.classList.contains("expanded")){expandButton=createScrapeButton(buttonHolder,"expand","Show all")}const isHidden=example.parentElement.classList.contains("more-scraped-examples");const locs=example.locs;if(locs.length>1){const next=createScrapeButton(buttonHolder,"next","Next usage");const prev=createScrapeButton(buttonHolder,"prev","Previous usage");const onChangeLoc=changeIndex=>{removeClass(highlights[locIndex],"focus");changeIndex();scrollToLoc(example,locs[locIndex][0],isHidden);addClass(highlights[locIndex],"focus");const url=locs[locIndex][1];const title=locs[locIndex][2];link.href=url;link.innerHTML=title};prev.addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex-1+locs.length)%locs.length})});next.addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex+1)%locs.length})})}if(expandButton){expandButton.addEventListener("click",()=>{if(hasClass(example,"expanded")){removeClass(example,"expanded");removeClass(expandButton,"collapse");expandButton.title="Show all";scrollToLoc(example,locs[0][0],isHidden)}else{addClass(example,"expanded");addClass(expandButton,"collapse");expandButton.title="Show single example"}})}};function setupLoc(example,isHidden){example.locs=JSON.parse(example.attributes.getNamedItem("data-locs").textContent);scrollToLoc(example,example.locs[0][0],isHidden)}const firstExamples=document.querySelectorAll(".scraped-example-list > .scraped-example");onEachLazy(firstExamples,el=>setupLoc(el,false));onEachLazy(document.querySelectorAll(".more-examples-toggle"),toggle=>{onEachLazy(toggle.querySelectorAll(".toggle-line, .hide-more"),button=>{button.addEventListener("click",()=>{toggle.open=false})});const moreExamples=toggle.querySelectorAll(".scraped-example");toggle.querySelector("summary").addEventListener("click",()=>{setTimeout(()=>{onEachLazy(moreExamples,el=>setupLoc(el,true))})},{once:true})})})()
|
||||
6
target/doc/static.files/search-e7298875.js
Normal file
6
target/doc/static.files/search-e7298875.js
Normal file
File diff suppressed because one or more lines are too long
17
target/doc/static.files/settings-d72f25bb.js
Normal file
17
target/doc/static.files/settings-d72f25bb.js
Normal file
@@ -0,0 +1,17 @@
|
||||
"use strict";(function(){const isSettingsPage=window.location.pathname.endsWith("/settings.html");function changeSetting(settingName,value){if(settingName==="theme"){const useSystem=value==="system preference"?"true":"false";updateLocalStorage("use-system-theme",useSystem)}updateLocalStorage(settingName,value);switch(settingName){case"theme":case"preferred-dark-theme":case"preferred-light-theme":updateTheme();updateLightAndDark();break;case"line-numbers":if(value===true){window.rustdoc_add_line_numbers_to_examples()}else{window.rustdoc_remove_line_numbers_from_examples()}break;case"hide-sidebar":if(value===true){addClass(document.documentElement,"hide-sidebar")}else{removeClass(document.documentElement,"hide-sidebar")}break;case"hide-toc":if(value===true){addClass(document.documentElement,"hide-toc")}else{removeClass(document.documentElement,"hide-toc")}break;case"hide-modnav":if(value===true){addClass(document.documentElement,"hide-modnav")}else{removeClass(document.documentElement,"hide-modnav")}break;case"sans-serif-fonts":if(value===true){addClass(document.documentElement,"sans-serif")}else{removeClass(document.documentElement,"sans-serif")}break;case"word-wrap-source-code":if(value===true){addClass(document.documentElement,"word-wrap-source-code")}else{removeClass(document.documentElement,"word-wrap-source-code")}break}}function showLightAndDark(){removeClass(document.getElementById("preferred-light-theme"),"hidden");removeClass(document.getElementById("preferred-dark-theme"),"hidden")}function hideLightAndDark(){addClass(document.getElementById("preferred-light-theme"),"hidden");addClass(document.getElementById("preferred-dark-theme"),"hidden")}function updateLightAndDark(){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||(useSystem===null&&getSettingValue("theme")===null)){showLightAndDark()}else{hideLightAndDark()}}function setEvents(settingsElement){updateLightAndDark();onEachLazy(settingsElement.querySelectorAll("input[type=\"checkbox\"]"),toggle=>{const settingId=toggle.id;const settingValue=getSettingValue(settingId);if(settingValue!==null){toggle.checked=settingValue==="true"}toggle.onchange=()=>{changeSetting(toggle.id,toggle.checked)}});onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"),elem=>{const settingId=elem.name;let settingValue=getSettingValue(settingId);if(settingId==="theme"){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||settingValue===null){settingValue=useSystem==="false"?"light":"system preference"}}if(settingValue!==null&&settingValue!=="null"){elem.checked=settingValue===elem.value}elem.addEventListener("change",ev=>{changeSetting(ev.target.name,ev.target.value)})})}function buildSettingsPageSections(settings){let output="";for(const setting of settings){if(setting==="hr"){output+="<hr>";continue}const js_data_name=setting["js_name"];const setting_name=setting["name"];if(setting["options"]!==undefined){output+=`\
|
||||
<div class="setting-line" id="${js_data_name}">
|
||||
<div class="setting-radio-name">${setting_name}</div>
|
||||
<div class="setting-radio-choices">`;onEach(setting["options"],option=>{const checked=option===setting["default"]?" checked":"";const full=`${js_data_name}-${option.replace(/ /g,"-")}`;output+=`\
|
||||
<label for="${full}" class="setting-radio">
|
||||
<input type="radio" name="${js_data_name}"
|
||||
id="${full}" value="${option}"${checked}>
|
||||
<span>${option}</span>
|
||||
</label>`});output+=`\
|
||||
</div>
|
||||
</div>`}else{const checked=setting["default"]===true?" checked":"";output+=`\
|
||||
<div class="setting-line">\
|
||||
<label class="setting-check">\
|
||||
<input type="checkbox" id="${js_data_name}"${checked}>\
|
||||
<span>${setting_name}</span>\
|
||||
</label>\
|
||||
</div>`}}return output}function buildSettingsPage(){const theme_names=getVar("themes").split(",").filter(t=>t);theme_names.push("light","dark","ayu");const settings=[{"name":"Theme","js_name":"theme","default":"system preference","options":theme_names.concat("system preference"),},{"name":"Preferred light theme","js_name":"preferred-light-theme","default":"light","options":theme_names,},{"name":"Preferred dark theme","js_name":"preferred-dark-theme","default":"dark","options":theme_names,},{"name":"Auto-hide item contents for large items","js_name":"auto-hide-large-items","default":true,},{"name":"Auto-hide item methods' documentation","js_name":"auto-hide-method-docs","default":false,},{"name":"Auto-hide trait implementation documentation","js_name":"auto-hide-trait-implementations","default":false,},{"name":"Directly go to item in search if there is only one result","js_name":"go-to-only-result","default":false,},{"name":"Show line numbers on code examples","js_name":"line-numbers","default":false,},{"name":"Hide persistent navigation bar","js_name":"hide-sidebar","default":false,},{"name":"Hide table of contents","js_name":"hide-toc","default":false,},{"name":"Hide module navigation","js_name":"hide-modnav","default":false,},{"name":"Disable keyboard shortcuts","js_name":"disable-shortcuts","default":false,},{"name":"Use sans serif fonts","js_name":"sans-serif-fonts","default":false,},{"name":"Word wrap source code","js_name":"word-wrap-source-code","default":false,},];const elementKind=isSettingsPage?"section":"div";const innerHTML=`<div class="settings">${buildSettingsPageSections(settings)}</div>`;const el=document.createElement(elementKind);el.id="settings";if(!isSettingsPage){el.className="popover"}el.innerHTML=innerHTML;if(isSettingsPage){document.getElementById(MAIN_ID).appendChild(el)}else{el.setAttribute("tabindex","-1");getSettingsButton().appendChild(el)}return el}const settingsMenu=buildSettingsPage();function displaySettings(){settingsMenu.style.display="";onEachLazy(settingsMenu.querySelectorAll("input[type='checkbox']"),el=>{const val=getSettingValue(el.id);const checked=val==="true";if(checked!==el.checked&&val!==null){el.checked=checked}})}function settingsBlurHandler(event){if(!getHelpButton().contains(document.activeElement)&&!getHelpButton().contains(event.relatedTarget)&&!getSettingsButton().contains(document.activeElement)&&!getSettingsButton().contains(event.relatedTarget)){window.hidePopoverMenus()}}if(!isSettingsPage){const settingsButton=getSettingsButton();const settingsMenu=document.getElementById("settings");settingsButton.onclick=event=>{if(settingsMenu.contains(event.target)){return}event.preventDefault();const shouldDisplaySettings=settingsMenu.style.display==="none";window.hideAllModals();if(shouldDisplaySettings){displaySettings()}};settingsButton.onblur=settingsBlurHandler;settingsButton.querySelector("a").onblur=settingsBlurHandler;onEachLazy(settingsMenu.querySelectorAll("input"),el=>{el.onblur=settingsBlurHandler});settingsMenu.onblur=settingsBlurHandler}setTimeout(()=>{setEvents(settingsMenu);if(!isSettingsPage){displaySettings()}removeClass(getSettingsButton(),"rotate")},0)})()
|
||||
1
target/doc/static.files/src-script-63605ae7.js
Normal file
1
target/doc/static.files/src-script-63605ae7.js
Normal file
@@ -0,0 +1 @@
|
||||
"use strict";(function(){const rootPath=getVar("root-path");const NAME_OFFSET=0;const DIRS_OFFSET=1;const FILES_OFFSET=2;const RUSTDOC_MOBILE_BREAKPOINT=700;function closeSidebarIfMobile(){if(window.innerWidth<RUSTDOC_MOBILE_BREAKPOINT){updateLocalStorage("source-sidebar-show","false")}}function createDirEntry(elem,parent,fullPath,hasFoundFile){const dirEntry=document.createElement("details");const summary=document.createElement("summary");dirEntry.className="dir-entry";fullPath+=elem[NAME_OFFSET]+"/";summary.innerText=elem[NAME_OFFSET];dirEntry.appendChild(summary);const folders=document.createElement("div");folders.className="folders";if(elem[DIRS_OFFSET]){for(const dir of elem[DIRS_OFFSET]){if(createDirEntry(dir,folders,fullPath,false)){dirEntry.open=true;hasFoundFile=true}}}dirEntry.appendChild(folders);const files=document.createElement("div");files.className="files";if(elem[FILES_OFFSET]){const w=window.location.href.split("#")[0];for(const file_text of elem[FILES_OFFSET]){const file=document.createElement("a");file.innerText=file_text;file.href=rootPath+"src/"+fullPath+file_text+".html";file.addEventListener("click",closeSidebarIfMobile);if(!hasFoundFile&&w===file.href){file.className="selected";dirEntry.open=true;hasFoundFile=true}files.appendChild(file)}}dirEntry.appendChild(files);parent.appendChild(dirEntry);return hasFoundFile}window.rustdocCloseSourceSidebar=()=>{removeClass(document.documentElement,"src-sidebar-expanded");updateLocalStorage("source-sidebar-show","false")};window.rustdocShowSourceSidebar=()=>{addClass(document.documentElement,"src-sidebar-expanded");updateLocalStorage("source-sidebar-show","true")};window.rustdocToggleSrcSidebar=()=>{if(document.documentElement.classList.contains("src-sidebar-expanded")){window.rustdocCloseSourceSidebar()}else{window.rustdocShowSourceSidebar()}};function createSrcSidebar(){const container=nonnull(document.querySelector("nav.sidebar"));const sidebar=document.createElement("div");sidebar.id="src-sidebar";let hasFoundFile=false;for(const[key,source]of srcIndex){source[NAME_OFFSET]=key;hasFoundFile=createDirEntry(source,sidebar,"",hasFoundFile)}container.appendChild(sidebar);const selected_elem=sidebar.getElementsByClassName("selected")[0];if(typeof selected_elem!=="undefined"){selected_elem.focus()}}function highlightSrcLines(){const match=window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);if(!match){return}let from=parseInt(match[1],10);let to=from;if(typeof match[2]!=="undefined"){to=parseInt(match[2],10)}if(to<from){const tmp=to;to=from;from=tmp}const from_s=""+from;let elem=document.getElementById(from_s);if(!elem){return}const x=document.getElementById(from_s);if(x){x.scrollIntoView()}onEachLazy(document.querySelectorAll("a[data-nosnippet]"),e=>{removeClass(e,"line-highlighted")});for(let i=from;i<=to;++i){elem=document.getElementById(""+i);if(!elem){break}addClass(elem,"line-highlighted")}}const handleSrcHighlight=(function(){let prev_line_id=0;const set_fragment=name=>{const x=window.scrollX,y=window.scrollY;if(browserSupportsHistoryApi()){history.replaceState(null,"","#"+name);highlightSrcLines()}else{location.replace("#"+name)}window.scrollTo(x,y)};return ev=>{let cur_line_id=parseInt(ev.target.id,10);if(isNaN(cur_line_id)||ev.ctrlKey||ev.altKey||ev.metaKey){return}ev.preventDefault();if(ev.shiftKey&&prev_line_id){if(prev_line_id>cur_line_id){const tmp=prev_line_id;prev_line_id=cur_line_id;cur_line_id=tmp}set_fragment(prev_line_id+"-"+cur_line_id)}else{prev_line_id=cur_line_id;set_fragment(""+cur_line_id)}}}());window.addEventListener("hashchange",highlightSrcLines);onEachLazy(document.querySelectorAll("a[data-nosnippet]"),el=>{el.addEventListener("click",handleSrcHighlight)});highlightSrcLines();window.createSrcSidebar=createSrcSidebar})()
|
||||
23
target/doc/static.files/storage-82c7156e.js
Normal file
23
target/doc/static.files/storage-82c7156e.js
Normal file
File diff suppressed because one or more lines are too long
9
target/doc/trait.impl/core/clone/trait.Clone.js
Normal file
9
target/doc/trait.impl/core/clone/trait.Clone.js
Normal file
@@ -0,0 +1,9 @@
|
||||
(function() {
|
||||
var implementors = Object.fromEntries([["chrs_bubble",[["impl <a class=\"trait\" href=\"https://doc.rust-lang.org/1.87.0/core/clone/trait.Clone.html\" title=\"trait core::clone::Clone\">Clone</a> for <a class=\"enum\" href=\"chrs_bubble/enum.ProvenanceEdge.html\" title=\"enum chrs_bubble::ProvenanceEdge\">ProvenanceEdge</a>"]]],["chrs_mail",[["impl <a class=\"trait\" href=\"https://doc.rust-lang.org/1.87.0/core/clone/trait.Clone.html\" title=\"trait core::clone::Clone\">Clone</a> for <a class=\"struct\" href=\"chrs_mail/struct.Message.html\" title=\"struct chrs_mail::Message\">Message</a>"]]],["chrs_slurp",[["impl <a class=\"trait\" href=\"https://doc.rust-lang.org/1.87.0/core/clone/trait.Clone.html\" title=\"trait core::clone::Clone\">Clone</a> for <a class=\"struct\" href=\"chrs_slurp/struct.DecisionRecord.html\" title=\"struct chrs_slurp::DecisionRecord\">DecisionRecord</a>"]]],["ucxl",[["impl <a class=\"trait\" href=\"https://doc.rust-lang.org/1.87.0/core/clone/trait.Clone.html\" title=\"trait core::clone::Clone\">Clone</a> for <a class=\"enum\" href=\"ucxl/enum.TemporalAxis.html\" title=\"enum ucxl::TemporalAxis\">TemporalAxis</a>"],["impl <a class=\"trait\" href=\"https://doc.rust-lang.org/1.87.0/core/clone/trait.Clone.html\" title=\"trait core::clone::Clone\">Clone</a> for <a class=\"struct\" href=\"ucxl/struct.UCXLAddress.html\" title=\"struct ucxl::UCXLAddress\">UCXLAddress</a>"]]]]);
|
||||
if (window.register_implementors) {
|
||||
window.register_implementors(implementors);
|
||||
} else {
|
||||
window.pending_implementors = implementors;
|
||||
}
|
||||
})()
|
||||
//{"start":57,"fragment_lengths":[290,270,294,520]}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user