Skip to content

Commit

Permalink
Convenience impls for LBString
Browse files Browse the repository at this point in the history
  • Loading branch information
kotauskas committed Apr 5, 2020
1 parent ff3d613 commit 188ef21
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 33 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bigbit"
version = "0.0.6"
version = "0.0.7"
authors = ["Kotauskas <[email protected]>"]
edition = "2018"
description = "Implements the BigBig format, allowing for compact storage of arbitrarily large numbers."
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ And here's a list of what's not finished just yet:
- **Tests** (planned for 0.1.0 but might be partially added earlier)

## Changelog
### 0.0.7
- Implemented some traits for `LBString`s, allowing for quick conversion to and from `String`s
### 0.0.6
- Added `LBString`, which is an owned string type implementing the Linked Bytes Unicode encoding, allowing for efficient storage of Unicode strings which is under all circumstances more compact than all current UTF encodings
- Added `LBNumRef` addition, which was missing due to a copypasting mistake
### 0.0.5
- Implemented arithmetic with `self` as the right operand for Linked Bytes, removing the need to always explicitly write `op1 + &op2` (same for other operators)
- Fixed the Crates.io badge to link to `bigbit` instead of `bi`**`t`**`bit`
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
//! - **Tests** (planned for 0.1.0 but might be partially added earlier)
//!
//! # Changelog
//! ## 0.0.7
//! - Implemented some traits for `LBString`s, allowing for quick conversion to and from `String`s
//! ## 0.0.6
//! - Added `LBString`, which is an owned string type implementing the Linked Bytes Unicode encoding, allowing for efficient storage of Unicode strings which is under all circumstances more compact than all current UTF encodings
//! - Added `LBNumRef` addition, which was missing due to a copypasting mistake
Expand Down
46 changes: 16 additions & 30 deletions src/linkedbytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
//!
//! If you only want non-negative integers, you should stick to this format. (Signed LB integers are also planned.) Otherwise, use either Head Byte or Extended Head Byte.
use core::slice::SliceIndex;
use alloc::{vec::Vec, string::String};
use core::{slice::SliceIndex, cmp::Ordering};
use alloc::vec::Vec;

/// The `Result` specialization for the methods converting iterators/arrays of bytes into instances of `LBNum`.
pub type DecodeResult = Result<LBNum, InvalidLBSequence>;
Expand Down Expand Up @@ -318,6 +318,18 @@ impl LBString {
LBCharsIter::new(self)
}

/// Counts the number of **codepoints** stored.
///
/// This will iterate through the entire string and count how many codepoints were resolved successfully. Currently, this is implemented as simply `self.chars().count()`.
#[inline(always)]
pub fn len(&self) -> usize {
self.chars().count()
}
/// Returns `true` if there are no codepoints stored, `false` otherwise.
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.0.is_empty() // We can use the container length, since if it's 0, then it's pointless to try to iterate, otherwise there's guaranteed to be a codepoint.
}
/// Returns an immutable reference to the underlying sequence.
#[inline(always)]
pub fn inner(&self) -> &LBSequence {
Expand All @@ -344,30 +356,6 @@ impl<'a> core::iter::FromIterator<&'a char> for LBString {
iter.into_iter().copied().collect::<Self>()
}
}
impl From<&String> for LBString {
#[inline(always)]
fn from(op: &String) -> Self {
op.chars().collect::<Self>()
}
}
impl From<String> for LBString {
#[inline(always)]
fn from(op: String) -> Self {
op.chars().collect::<Self>()
}
}
impl<'a> From<&'a str> for LBString {
#[inline(always)]
fn from(op: &'a str) -> Self {
op.chars().collect::<Self>()
}
}
impl From<LBString> for String {
#[inline(always)]
fn from(op: LBString) -> Self {
op.chars().collect::<Self>()
}
}
impl core::fmt::Display for LBString {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
use core::fmt::Write;
Expand Down Expand Up @@ -731,15 +719,13 @@ impl core::fmt::Debug for LinkedByte {
ds.finish()
}
}

use core::cmp::{self, Ordering};
impl cmp::PartialOrd for LinkedByte {
impl PartialOrd for LinkedByte {
#[inline(always)]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl cmp::Ord for LinkedByte {
impl Ord for LinkedByte {
#[inline(always)]
fn cmp(&self, other: &Self) -> Ordering {
self.into_end().0.cmp(&other.into_end().0)
Expand Down
81 changes: 81 additions & 0 deletions src/ops/lbstring/cmp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use crate::LBString;
use alloc::string::String;
use core::cmp::Ordering; // We're not gonna deal with atomics here, right?

impl PartialEq for LBString {
#[inline(always)]
fn eq(&self, rhs: &Self) -> bool {
self.cmp(rhs) == Ordering::Equal
}
}
impl Eq for LBString {}
impl PartialOrd for LBString {
#[inline(always)]
fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
Some(self.cmp(rhs))
}
}
impl Ord for LBString {
#[inline]
fn cmp(&self, rhs: &Self) -> Ordering {
let (mut chars_l, mut chars_r) = (self.chars(), rhs.chars());
loop {
let (l, r) = (chars_l.next(), chars_r.next());
if let Some(l_val) = l {
if let Some(r_val) = r {
match l_val.cmp(&r_val) {
Ordering::Greater => {return Ordering::Greater;},
Ordering::Less => {return Ordering::Less;},
Ordering::Equal => {}
}
} else {return Ordering::Greater;}
} else if r.is_some() {return Ordering::Less;} else {break;}
}
Ordering::Equal
}
}

macro_rules! impl_pcmp_for_chars {
($ty:ident) => {
impl PartialEq<$ty> for LBString {
#[inline(always)]
fn eq(&self, rhs: &$ty) -> bool {
self.partial_cmp(rhs) == Some(Ordering::Equal)
}
}
impl PartialOrd<$ty> for LBString {
fn partial_cmp(&self, rhs: &$ty) -> Option<Ordering> {
let (mut chars_l, mut chars_r) = (self.chars(), rhs.chars());
loop {
let (l, r) = (chars_l.next(), chars_r.next());
if let Some(l_val) = l {
if let Some(r_val) = r {
match l_val.cmp(&r_val) {
Ordering::Greater => {return Some(Ordering::Greater);},
Ordering::Less => {return Some(Ordering::Less);},
Ordering::Equal => {}
}
} else {return Some(Ordering::Greater);}
} else if r.is_some() {return Some(Ordering::Less);} else {break;}
}
Some(Ordering::Equal)
}
}

impl PartialEq<LBString> for $ty {
#[inline(always)]
fn eq(&self, rhs: &LBString) -> bool {
self.partial_cmp(rhs) == Some(Ordering::Equal)
}
}
impl PartialOrd<LBString> for $ty {
#[inline(always)]
fn partial_cmp(&self, rhs: &LBString) -> Option<Ordering> {
rhs.partial_cmp(self)
}
}
};
}

impl_pcmp_for_chars!(String);
impl_pcmp_for_chars!(str);
21 changes: 21 additions & 0 deletions src/ops/lbstring/from.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use alloc::string::String;
use crate::LBString;

impl From<&String> for LBString {
#[inline(always)]
fn from(op: &String) -> Self {
op.chars().collect::<Self>()
}
}
impl From<String> for LBString {
#[inline(always)]
fn from(op: String) -> Self {
op.chars().collect::<Self>()
}
}
impl<'a> From<&'a str> for LBString {
#[inline(always)]
fn from(op: &'a str) -> Self {
op.chars().collect::<Self>()
}
}
9 changes: 9 additions & 0 deletions src/ops/lbstring/into.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use alloc::string::String;
use crate::LBString;

impl From<LBString> for String {
#[inline(always)]
fn from(op: LBString) -> Self {
op.chars().collect::<Self>()
}
}
3 changes: 3 additions & 0 deletions src/ops/lbstring/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod from; mod into; mod cmp;
#[allow(unused_imports)]
pub(crate) use {from::*, into::*, cmp::*};
5 changes: 3 additions & 2 deletions src/ops/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Uncomment when implementing arithmetics for these
// Uncomment when implementing operations for these
//pub(crate) mod headbyte;
//pub(crate) mod extheadbyte;
pub(crate) mod linkedbytes;
pub(crate) mod linkedbytes;
pub(crate) mod lbstring;

0 comments on commit 188ef21

Please sign in to comment.