From 7111040b316fe29a596690d3953ee2521854ffdc Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Thu, 20 Feb 2020 18:43:45 -0600 Subject: [PATCH] list impl --- Cargo.lock | 157 +++++++++++++++++++++++++++++ Cargo.toml | 5 + examples/helloworld/src/main.rs | 4 +- examples/todomvc/Cargo.toml | 9 +- examples/todomvc/src/build.rs | 19 ++++ examples/todomvc/src/main.rs | 17 +++- examples/todomvc/static/index.html | 11 ++ src/lib.rs | 5 + src/std/list.rs | 156 ++++++++++++++++++++++++++++ src/std/mod.rs | 5 + 10 files changed, 383 insertions(+), 5 deletions(-) create mode 100644 examples/todomvc/src/build.rs create mode 100644 examples/todomvc/static/index.html create mode 100644 src/std/list.rs create mode 100644 src/std/mod.rs diff --git a/Cargo.lock b/Cargo.lock index bf34af5..b985cc9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,13 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "aho-corasick" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "autocfg" version = "1.0.0" @@ -28,6 +36,14 @@ name = "bumpalo" version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "c2-chacha" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cfg-if" version = "0.1.10" @@ -52,7 +68,10 @@ version = "0.1.0" dependencies = [ "enterprise-compiler 0.1.0", "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quickcheck 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "quickcheck_macros 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "stdweb 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", + "symbol 0.1.0", ] [[package]] @@ -88,11 +107,30 @@ dependencies = [ "thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fixedbitset" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "getrandom" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "helloworld" version = "0.1.0" @@ -147,6 +185,11 @@ name = "maplit" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "memchr" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "parking_lot" version = "0.10.0" @@ -178,6 +221,11 @@ dependencies = [ "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ppv-lite86" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "proc-macro2" version = "1.0.8" @@ -186,6 +234,27 @@ dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "quickcheck" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quickcheck_macros" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "quote" version = "1.0.2" @@ -194,11 +263,64 @@ dependencies = [ "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_chacha" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "redox_syscall" version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "regex" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rustc_version" version = "0.2.3" @@ -370,15 +492,34 @@ dependencies = [ "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "thread_local" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "todomvc" version = "0.1.0" +dependencies = [ + "enterprise 0.1.0", + "enterprise-compiler 0.1.0", + "enterprise-macros 0.1.0", + "stdweb 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "unicode-xid" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "wasm-bindgen" version = "0.2.58" @@ -448,15 +589,19 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] +"checksum aho-corasick 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "743ad5a418686aad3b87fd14c43badd828cf26e214a00f92a384291cf22e1811" "checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" "checksum base-x 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b20b618342cf9891c292c4f5ac2cde7287cc5c87e87e9c769d617793607dec1" "checksum bimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "783204f24fd7724ea274d327619cfa6a6018047bb0561a68aadff6f56787591b" "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" "checksum bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb8038c1ddc0a5f73787b130f4cc75151e96ed33e417fde765eb5a81e3532f4" +"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum discard 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" +"checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" "checksum fixedbitset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" +"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" "checksum indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b54058f0a6ff80b6803da8faf8997cde53872b38f4023728f6830b06cd3c0dc" "checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" @@ -464,12 +609,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lock_api 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "79b2de95ecb4691949fea4716ca53cdbcfccb2c612e19644a8bad05edcf9f47b" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" "checksum maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" +"checksum memchr 2.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53445de381a1f436797497c61d851644d0e8e88e6140f22872ad33a704933978" "checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" "checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" "checksum petgraph 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29c127eea4a29ec6c85d153c59dc1213f33ec74cead30fe4730aecc88cc1fd92" +"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" "checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" +"checksum quickcheck 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f" +"checksum quickcheck_macros 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "608c156fd8e97febc07dc9c2e2c80bf74cfc6ef26893eae3daf8bc2bc94a4b7f" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" +"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" +"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +"checksum regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8" +"checksum regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" "checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" @@ -488,7 +643,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" "checksum thiserror 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ee14bf8e6767ab4c687c9e8bc003879e042a96fd67a3ba5934eadb6536bef4db" "checksum thiserror-impl 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "a7b51e1fbc44b5a0840be594fbc0f960be09050f2617e61e6aa43bef97cd3ef4" +"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" "checksum wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "5205e9afdf42282b192e2310a5b463a6d1c1d774e30dc3c791ac37ab42d2616c" "checksum wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "11cdb95816290b525b32587d76419facd99662a07e59d3cdb560488a819d9a45" "checksum wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "574094772ce6921576fb6f2e3f7497b8a76273b6db092be18fc48a082de09dc3" diff --git a/Cargo.toml b/Cargo.toml index 88e6fb1..40dd2a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,12 @@ members = [ default = ["web"] web = ["stdweb"] +[dev-dependencies] +quickcheck = "0.9.2" +quickcheck_macros = "0.9.1" + [dependencies] enterprise-compiler = { path = "enterprise-compiler" } stdweb = { version = "0.4.20", optional = true } parking_lot = "0.10.0" +symbol = { path = "symbol" } diff --git a/examples/helloworld/src/main.rs b/examples/helloworld/src/main.rs index eb8d722..fc36228 100644 --- a/examples/helloworld/src/main.rs +++ b/examples/helloworld/src/main.rs @@ -3,9 +3,7 @@ extern crate enterprise; enterprise_mod!(helloworld); -use std::sync::Arc; - -use enterprise::{Backend, Component, Web}; +use enterprise::{Backend, Web}; use crate::helloworld::HelloWorld; diff --git a/examples/todomvc/Cargo.toml b/examples/todomvc/Cargo.toml index b9533e8..045cca7 100644 --- a/examples/todomvc/Cargo.toml +++ b/examples/todomvc/Cargo.toml @@ -3,7 +3,14 @@ name = "todomvc" version = "0.1.0" authors = ["Michael Zhang "] edition = "2018" +build = "src/build.rs" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[build-dependencies] +enterprise-compiler = { path = "../../enterprise-compiler" } +enterprise-macros = { path = "../../enterprise-macros" } +enterprise = { path = "../.." } [dependencies] +stdweb = "0.4.20" +enterprise-macros = { path = "../../enterprise-macros" } +enterprise = { path = "../.." } diff --git a/examples/todomvc/src/build.rs b/examples/todomvc/src/build.rs new file mode 100644 index 0000000..357cb9f --- /dev/null +++ b/examples/todomvc/src/build.rs @@ -0,0 +1,19 @@ +#[macro_use] +extern crate enterprise_macros; + +component! { + component TodoMVC { + model { + todos: List = List::new(), + } + + view { + + "Hello, " {name} "!" + } + } +} + +fn main() { + enterprise_compiler::process("todomvc", TodoMVC); +} diff --git a/examples/todomvc/src/main.rs b/examples/todomvc/src/main.rs index e7a11a9..44db389 100644 --- a/examples/todomvc/src/main.rs +++ b/examples/todomvc/src/main.rs @@ -1,3 +1,18 @@ +#[macro_use] +extern crate enterprise; + +enterprise_mod!(todomvc); + +use enterprise::{Backend, Web}; + +use crate::todomvc::TodoMVC; + fn main() { - println!("Hello, world!"); + stdweb::initialize(); + + let web = Web; + let app = TodoMVC::new(&web); + web.initialize(app, "app".into()); + + stdweb::event_loop(); } diff --git a/examples/todomvc/static/index.html b/examples/todomvc/static/index.html new file mode 100644 index 0000000..2665f62 --- /dev/null +++ b/examples/todomvc/static/index.html @@ -0,0 +1,11 @@ + + + + + what the Hek + + +
+ + + diff --git a/src/lib.rs b/src/lib.rs index ff93fda..7405914 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,8 +8,13 @@ pub extern crate enterprise_compiler; pub extern crate parking_lot; pub extern crate stdweb; +#[cfg(test)] +#[macro_use(quickcheck)] +extern crate quickcheck_macros; + mod backend; pub mod compiler; +pub mod std; pub use crate::backend::{Backend, Web}; diff --git a/src/std/list.rs b/src/std/list.rs new file mode 100644 index 0000000..90b67c1 --- /dev/null +++ b/src/std/list.rs @@ -0,0 +1,156 @@ +use std::marker::PhantomData; +use std::fmt::{self, Debug, Formatter}; +use std::collections::HashMap; +use std::ptr::NonNull; + +use symbol::Symbol; + +/// A list that guarantees: +/// - O(1) insertion +/// - O(1) deletion +/// - O(1) iteration +pub struct List { + head: Option>>, + tail: Option>>, + map: HashMap>>, +} + +struct Node { + prev: Option>>, + next: Option>>, + data: T, +} + +/// Referential iterator +pub struct Iter<'a, T>(Option>>, PhantomData<&'a T>); + +impl<'a, T> Iterator for Iter<'a, T> { + type Item = &'a T; + + fn next(&mut self) -> Option { + if let Some(node) = self.0 { + self.0 = unsafe { (*node.as_ptr()).next }; + Some(unsafe { &(*node.as_ptr()).data }) + } else { + None + } + } +} + +/// Item iterator +pub struct IntoIter(Option>>); + +impl Iterator for IntoIter { + type Item = Box; + + fn next(&mut self) -> Option { + if let Some(node) = self.0 { + let node_ptr = node.as_ptr(); + self.0 = unsafe { (*node_ptr).next }; + Some(unsafe { Box::from_raw(&mut (*node_ptr).data) }) + } else { + None + } + } +} + +impl Default for List { + fn default() -> Self { + List { + head: None, + tail: None, + map: HashMap::new(), + } + } +} + +impl Clone for List { + fn clone(&self) -> Self { + let mut new_list = List::new(); + for item in self.iter() { + new_list.insert(item.clone()); + } + new_list + } +} + +impl Debug for List { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "[")?; + let mut is_first = true; + for item in self.iter() { + if is_first { + is_first = false; + } else { + write!(f, ", ")?; + } + write!(f, "{:?}", item)?; + } + write!(f, "]")?; + Ok(()) + } +} + +impl List { + /// Creates a new List + pub fn new() -> Self { + List::default() + } + + /// Creates an iterator for the list + pub fn iter<'a>(&'a self) -> Iter<'a, T> { + Iter(self.head, PhantomData::default()) + } + + /// Creates a consuming iterator for the list + pub fn into_iter(self) -> IntoIter { + IntoIter(self.head) + } + + /// Returns the tail of the list + pub fn tail(&self) -> Option<&T> { + if let Some(ref node) = self.tail { + Some(&unsafe { node.as_ref() }.data) + } else { + None + } + } + + /// Inserts the specified item into the list + pub fn insert(&mut self, item: T) -> Symbol { + let node = Node { + prev: None, + next: None, + data: item, + }; + let mut node = unsafe { NonNull::new_unchecked(Box::into_raw(Box::new(node))) }; + let new_key = Symbol::gensym(); + + if let Some(ref mut tail) = self.tail { + (*unsafe { node.as_mut() }).prev = Some(*tail); + (*unsafe { tail.as_mut() }).next = Some(node); + } + + if let None = self.head { + self.head = Some(node); + } + self.tail = Some(node); + + self.map.insert(new_key, node); + new_key + } +} + +#[cfg(test)] +mod tests { + use super::List; + + #[quickcheck] + fn list_equivalence(vec: Vec) -> bool { + let mut list = List::new(); + for item in vec.iter() { + list.insert(*item); + } + list.iter().eq(vec.iter()) + } +} diff --git a/src/std/mod.rs b/src/std/mod.rs new file mode 100644 index 0000000..8af9a51 --- /dev/null +++ b/src/std/mod.rs @@ -0,0 +1,5 @@ +//! Standard modules + +mod list; + +pub use self::list::List;