use super::{
super::{borrow::*, immutable::*, iter::*},
foster::*,
has_length::*,
iterator::*,
};
use std::{cmp::*, hash::*, slice::*};
pub type FosterImmutableStringVector = Foster<Vec<ImmutableString>, &'static [&'static str]>;
impl IntoOwned for FosterImmutableStringVector {
fn into_owned(self) -> Self {
match self {
Self::Owned(_) => self,
Self::Fostered(strings) => Self::new_owned(strings.iter().map(|string| (*string).into()).collect()),
}
}
}
impl HasLength for FosterImmutableStringVector {
fn len(&self) -> usize {
match self {
Self::Owned(strings) => strings.len(),
Self::Fostered(strings) => strings.len(),
}
}
}
impl PartialEq for FosterImmutableStringVector {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Owned(left), Self::Owned(right)) => left == right,
(Self::Owned(left), Self::Fostered(right)) => {
if left.len() == right.len() {
let mut equal = true;
for (index, left) in left.iter().enumerate() {
if left != right[index] {
equal = false;
break;
}
}
equal
} else {
false
}
}
(Self::Fostered(left), Self::Owned(right)) => {
if left.len() == right.len() {
let mut equal = true;
for (index, left) in left.iter().enumerate() {
let right: &str = &right[index];
if *left != right {
equal = false;
break;
}
}
equal
} else {
false
}
}
(Self::Fostered(left), Self::Fostered(right)) => left == right,
}
}
}
impl Eq for FosterImmutableStringVector {}
impl PartialOrd for FosterImmutableStringVector {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
match (self, other) {
(Self::Owned(left), Self::Owned(right)) => left.partial_cmp(right),
(Self::Owned(left), Self::Fostered(right)) => {
let left_length = left.len();
let right_length = right.len();
let length = min(left_length, right_length);
let left_bounded = &left[..length];
let right_bounded = &right[..length];
for index in 0..length {
match (*left_bounded[index]).partial_cmp(right_bounded[index]) {
Some(Ordering::Equal) => {}
not_equal => return not_equal,
}
}
left_length.partial_cmp(&right_length)
}
(Self::Fostered(left), Self::Owned(right)) => {
let left_length = left.len();
let right_length = right.len();
let length = min(left_length, right_length);
let left_bounded = &left[..length];
let right_bounded = &right[..length];
for index in 0..length {
let right_bounded: &str = &right_bounded[index];
match left_bounded[index].partial_cmp(right_bounded) {
Some(Ordering::Equal) => {}
not_equal => return not_equal,
}
}
left_length.partial_cmp(&right_length)
}
(Self::Fostered(left), Self::Fostered(right)) => left.partial_cmp(right),
}
}
}
impl Ord for FosterImmutableStringVector {
fn cmp(&self, other: &Self) -> Ordering {
match (self, other) {
(Self::Owned(left), Self::Owned(right)) => left.cmp(right),
(Self::Owned(left), Self::Fostered(right)) => {
let left_length = left.len();
let right_length = right.len();
let length = min(left_length, right_length);
let left_bounded = &left[..length];
let right_bounded = &right[..length];
for index in 0..length {
match (*left_bounded[index]).cmp(right_bounded[index]) {
Ordering::Equal => {}
not_equal => return not_equal,
}
}
left_length.cmp(&right_length)
}
(Self::Fostered(left), Self::Owned(right)) => {
let left_length = left.len();
let right_length = right.len();
let length = min(left_length, right_length);
let left_bounded = &left[..length];
let right_bounded = &right[..length];
for index in 0..length {
let right_bounded: &str = &right_bounded[index];
match left_bounded[index].cmp(right_bounded) {
Ordering::Equal => {}
not_equal => return not_equal,
}
}
left_length.cmp(&right_length)
}
(Self::Fostered(left), Self::Fostered(right)) => left.cmp(right),
}
}
}
impl Hash for FosterImmutableStringVector {
fn hash<HasherT>(&self, state: &mut HasherT)
where
HasherT: Hasher,
{
match self {
Self::Owned(strings) => {
for string in strings {
state.write(string.as_bytes());
}
}
Self::Fostered(strings) => {
for string in strings.iter() {
state.write(string.as_bytes());
}
}
}
}
}
impl<'this> IntoIterator for &'this FosterImmutableStringVector {
type Item = &'this str;
type IntoIter = FosterIterator<
&'this str,
&'this ImmutableString,
&'this &'static str,
Iter<'this, ImmutableString>,
Iter<'this, &'static str>,
>;
fn into_iter(self) -> Self::IntoIter {
match self {
Foster::Owned(strings) => {
Foster::new_owned(ConvertingIterator::new(strings.iter(), |string| Some(&string)))
}
Foster::Fostered(strings) => {
Foster::new_fostered(ConvertingIterator::new(strings.iter(), |string| Some(string)))
}
}
}
}
#[macro_export]
macro_rules! delegate_newtype_of_foster_byte_string_vector {
( $type:ty $(,)? ) => {
impl $type {
pub fn new_owned(strings: ::std::vec::Vec<$crate::std::immutable::ImmutableString>) -> Self {
Self($crate::std::foster::Foster::new_owned(strings))
}
pub const fn new_fostered(strings: &'static [&'static str]) -> Self {
Self($crate::std::foster::Foster::new_fostered(strings))
}
}
impl $crate::std::borrow::IntoOwned for $type {
fn into_owned(self) -> Self {
match self.0 {
$crate::std::foster::Foster::Owned(_) => self,
$crate::std::foster::Foster::Fostered(_) => Self(self.0.into_owned()),
}
}
}
impl $crate::std::foster::HasLength for $type {
fn len(&self) -> usize {
self.0.len()
}
}
impl ::std::convert::From<::std::vec::Vec<$crate::std::immutable::ImmutableString>> for $type {
fn from(strings: Vec<$crate::std::immutable::ImmutableString>) -> Self {
strings.into()
}
}
impl ::std::cmp::PartialEq for $type {
fn eq(&self, other: &Self) -> bool {
self.0.eq(&other.0)
}
}
impl ::std::cmp::Eq for $type {}
impl ::std::cmp::PartialOrd for $type {
fn partial_cmp(&self, other: &Self) -> ::std::option::Option<::std::cmp::Ordering> {
self.0.partial_cmp(&other.0)
}
}
impl ::std::cmp::Ord for $type {
fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
self.0.cmp(&other.0)
}
}
impl ::std::hash::Hash for $type {
fn hash<HasherT>(&self, state: &mut HasherT)
where
HasherT: ::std::hash::Hasher,
{
self.0.hash(state)
}
}
impl<'this> ::std::iter::IntoIterator for &'this $type {
type Item = &'this str;
type IntoIter = $crate::std::foster::FosterIterator<
&'this str,
&'this $crate::std::immutable::ImmutableString,
&'this &'static str,
::std::slice::Iter<'this, $crate::std::immutable::ImmutableString>,
::std::slice::Iter<'this, &'static str>,
>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
};
}
#[allow(unused_imports)]
pub use delegate_newtype_of_foster_byte_string_vector as delegate_newtype_of_foster_immutable_string_vector;