/ src / lib.rs
lib.rs
  1  #![doc = include_str!("../README.md")]
  2  // uncomment for discovering new lints:
  3  // #![deny(clippy::all, clippy::pedantic, clippy::nursery, clippy::cargo)]
  4  #![warn(clippy::cargo_common_metadata)]
  5  #![warn(clippy::doc_markdown)]
  6  #![warn(clippy::missing_panics_doc)]
  7  #![warn(clippy::must_use_candidate)]
  8  #![warn(clippy::semicolon_if_nothing_returned)]
  9  #![warn(missing_docs)]
 10  #![warn(rustdoc::missing_crate_level_docs)]
 11  
 12  use cowstr::{SubStr, EMPTY_SUBSTR};
 13  
 14  use constptr::ConstPtr;
 15  
 16  /// A `StrStr` is a dynamic string made from a tree of immutable `SubStr's`. Inserting and
 17  /// removing data only needs to adjust the tree instead shifting characters around.
 18  pub struct StrStr {
 19      subs: Node,
 20  }
 21  
 22  /// The nodes linking a `StrStr` tree together.
 23  /// This tree must be kept normalized, that means empty Leaves are removed, except when at the root.
 24  /// Operations may try to optimize it ins several ways.
 25  enum Node {
 26      // Leafs containing `SubStr's`. There is no parent pointer here to minimize the size of
 27      // this enum. When traversing its enough to cache the last branch.
 28      Str(SubStr),
 29      // A branch, pointing to sub branches or leafs. Storing the parent here comes for free
 30      // since the Box is much smaller than a Str(SubStr).
 31      Concat { concat: Box<(Node, Node)>, parent: Option<ConstPtr<Node>> },
 32  }
 33  
 34  // ctors
 35  impl StrStr {
 36      /// Creates a empty `StrStr`
 37      fn new() -> Self {
 38          Self {
 39              subs: Node::Str(EMPTY_SUBSTR.clone()),
 40          }
 41      }
 42  }
 43  
 44  // mutation methods
 45  impl StrStr {
 46      pub fn append(&mut self) -> &mut Self { todo!()}
 47  
 48      pub fn prepend(&mut self) -> &mut Self { todo!()}
 49      
 50      pub fn insert(&mut self) -> &mut Self { todo!()}
 51  
 52      pub fn remove(&mut self) -> &mut Self { todo!()}
 53  }
 54  
 55  /*
 56  TODO: methods
 57      insert / Index
 58      remove ranges
 59  
 60      normalize/flatten
 61      optimize
 62      range -> &str
 63      -> iter<char>
 64      -> iter<u8>
 65      Extend
 66      regex/pattern api search/replace
 67      https://crates.io/crates/regex-automata
 68      undoable?
 69  
 70  TODO: impl traits:
 71  Add
 72  AddAssign
 73  Index
 74  Ord
 75  Eq
 76  Hash
 77   */
 78  
 79  // query methods
 80  impl StrStr {
 81      pub fn is_empty(&self) -> bool {
 82          match &self.subs {
 83              Node::Str(s) if s.len() == 0 => true,
 84              _ => false,
 85          }
 86      }
 87  }
 88  
 89  #[test]
 90  fn smoke() {
 91      let empty = StrStr::new();
 92      assert!(empty.is_empty());
 93  }
 94  
 95  #[test]
 96  fn expected_size() {
 97      // A Node should use a niche and be the same size as a SubStr.
 98      assert_eq!(std::mem::size_of::<SubStr>(), std::mem::size_of::<Node>());
 99  }
100  
101