parent
31ee30db9e
commit
633466b901
@ -1,2 +0,0 @@
|
||||
//! /sentance/
|
||||
use super::*;
|
@ -0,0 +1,27 @@
|
||||
//! Extensions
|
||||
use std::{
|
||||
iter,
|
||||
};
|
||||
|
||||
pub trait StringJoinExt: Sized
|
||||
{
|
||||
fn join<P: AsRef<str>>(self, sep: P) -> String;
|
||||
}
|
||||
|
||||
impl<I,T> StringJoinExt for I
|
||||
where I: IntoIterator<Item=T>,
|
||||
T: AsRef<str>
|
||||
{
|
||||
fn join<P: AsRef<str>>(self, sep: P) -> String
|
||||
{
|
||||
let mut string = String::new();
|
||||
for (first, s) in iter::successors(Some(true), |_| Some(false)).zip(self.into_iter())
|
||||
{
|
||||
if !first {
|
||||
string.push_str(sep.as_ref());
|
||||
}
|
||||
string.push_str(s.as_ref());
|
||||
}
|
||||
string
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
avril@eientei.880:1602382403
|
@ -0,0 +1,260 @@
|
||||
//! Filter out characters and such
|
||||
use smallmap::Map as SmallMap;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
fmt,
|
||||
iter::{
|
||||
self,
|
||||
FromIterator,
|
||||
},
|
||||
str,
|
||||
};
|
||||
use once_cell::sync::OnceCell;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Filter(SmallMap<char, ()>);
|
||||
|
||||
impl<const N: usize> From<[char; N]> for Filter
|
||||
{
|
||||
fn from(from: [char; N]) -> Self
|
||||
{
|
||||
let mut map = SmallMap::with_capacity(1 + (N / 256));
|
||||
for &chr in from.iter()
|
||||
{
|
||||
map.insert(chr, ());
|
||||
}
|
||||
Self(map)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a [char]> for Filter
|
||||
{
|
||||
fn from(from: &'a [char]) -> Self
|
||||
{
|
||||
let mut map = SmallMap::new();
|
||||
for &chr in from.iter()
|
||||
{
|
||||
map.insert(chr, ());
|
||||
}
|
||||
Self(map)
|
||||
}
|
||||
}
|
||||
impl<'a> From<&'a str> for Filter
|
||||
{
|
||||
fn from(from: &'a str) -> Self
|
||||
{
|
||||
let mut output = Self::new();
|
||||
output.insert(from.chars());
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
impl str::FromStr for Filter
|
||||
{
|
||||
type Err = std::convert::Infallible;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(Self::from(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Filter
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
||||
{
|
||||
use std::fmt::Write;
|
||||
for chr in self.iter()
|
||||
{
|
||||
f.write_char(chr)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FilterKeyIter<'a>(smallmap::iter::Iter<'a, char, ()>, usize);
|
||||
|
||||
impl<'a> Iterator for FilterKeyIter<'a>
|
||||
{
|
||||
type Item = char;
|
||||
fn next(&mut self) -> Option<Self::Item>
|
||||
{
|
||||
self.0.next().map(|&(x, _)| x)
|
||||
}
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
(self.1, Some(self.1))
|
||||
}
|
||||
}
|
||||
impl<'a> iter::FusedIterator for FilterKeyIter<'a>{}
|
||||
impl<'a> iter::ExactSizeIterator for FilterKeyIter<'a>{}
|
||||
|
||||
impl Filter
|
||||
{
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self(SmallMap::new())
|
||||
}
|
||||
pub fn insert<I: IntoIterator<Item=char>>(&mut self, from: I)
|
||||
{
|
||||
for from in from.into_iter()
|
||||
{
|
||||
self.0.insert(from, ());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove<I: IntoIterator<Item=char>>(&mut self, from: I)
|
||||
{
|
||||
for from in from.into_iter()
|
||||
{
|
||||
self.0.remove(&from);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize
|
||||
{
|
||||
self.0.len()
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool
|
||||
{
|
||||
//TODO: impl this in smallmap itself
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item=char> + '_
|
||||
{
|
||||
self.0.iter()
|
||||
.copied()
|
||||
.map(|(x, _)| x)
|
||||
//FilterKeyIter(self.0.iter(), self.0.len())
|
||||
}
|
||||
|
||||
/// Should this character be filtered?
|
||||
#[inline] pub fn check(&self, chr: char) -> bool
|
||||
{
|
||||
self.0.get(&chr).is_some()
|
||||
}
|
||||
|
||||
pub fn filter<'a, I: IntoIterator<Item=char>>(&'a self, from_iter: I) -> FilterIter<'a, I::IntoIter>
|
||||
where I::IntoIter: 'a
|
||||
{
|
||||
FilterIter(&self, from_iter.into_iter().fuse())
|
||||
}
|
||||
|
||||
pub fn filter_cow<'a>(&self, string: &'a (impl AsRef<str> + 'a + ?Sized)) -> Cow<'a, str>
|
||||
{
|
||||
let string = string.as_ref();
|
||||
|
||||
if self.is_empty() {
|
||||
return Cow::Borrowed(string);
|
||||
}
|
||||
|
||||
let mut output = Cow::Borrowed(string);
|
||||
let mut i=0;
|
||||
for chr in string.chars()
|
||||
{
|
||||
if self.check(chr) {
|
||||
output.to_mut().remove(i);
|
||||
} else {
|
||||
i+=1;
|
||||
}
|
||||
}
|
||||
|
||||
output
|
||||
}
|
||||
|
||||
pub fn filter_str<'a, T: AsRef<str>+'a>(&'a self, string: &'a T) -> FilterStr<'a>
|
||||
{
|
||||
FilterStr(string.as_ref(), self, OnceCell::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl FromIterator<char> for Filter
|
||||
{
|
||||
fn from_iter<I: IntoIterator<Item=char>>(iter: I) -> Self
|
||||
{
|
||||
let mut output= Self::new();
|
||||
output.insert(iter);
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FilterStr<'a>
|
||||
{
|
||||
pub fn as_str(&self) -> &str
|
||||
{
|
||||
fn fmt(this: &FilterStr<'_>) -> String
|
||||
{
|
||||
let chars = this.0.chars();
|
||||
let mut f: String = crate::util::hint_cap(&chars);
|
||||
for chr in chars {
|
||||
if !this.1.check(chr) {
|
||||
f.push(chr);
|
||||
}
|
||||
}
|
||||
f
|
||||
}
|
||||
&self.2.get_or_init(|| fmt(&self))[..]
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FilterStr<'a>(&'a str, &'a Filter, OnceCell<String>);
|
||||
impl<'a> fmt::Display for FilterStr<'a>
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
||||
{
|
||||
write!(f, "{}", self.as_str())
|
||||
}
|
||||
}
|
||||
impl<'a> FilterStr<'a>
|
||||
{
|
||||
pub fn filter(&self) -> &Filter
|
||||
{
|
||||
&self.1
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FilterIter<'a, I>(&'a Filter, iter::Fuse<I>);
|
||||
|
||||
impl<'a, I: Iterator<Item=char>> Iterator for FilterIter<'a, I>
|
||||
{
|
||||
type Item = char;
|
||||
fn next(&mut self) -> Option<Self::Item>
|
||||
{
|
||||
loop {
|
||||
break match self.1.next() {
|
||||
Some(chr) if !self.0.check(chr) => Some(chr),
|
||||
None => None,
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let (_, high) = self.1.size_hint();
|
||||
(0, high)
|
||||
}
|
||||
}
|
||||
impl<'a, I> FilterIter<'a, I>
|
||||
{
|
||||
pub fn filter(&self) -> &Filter
|
||||
{
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, I: Iterator<Item=char>> iter::FusedIterator for FilterIter<'a, I>{}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests
|
||||
{
|
||||
use super::*;
|
||||
#[test]
|
||||
fn filter_cow()
|
||||
{
|
||||
let filter: Filter = " hi".chars().collect();
|
||||
|
||||
let string = "abcdef ghi jk1\nhian";
|
||||
|
||||
assert_eq!(filter.filter_str(&string).to_string(), filter.filter_cow(&string).to_string());
|
||||
assert_eq!(filter.filter_cow(&string).to_string(), filter.filter(string.chars()).collect::<String>());
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
//! /sentance/
|
||||
use super::*;
|
||||
|
||||
pub async fn body(state: State, num: Option<usize>, mut output: mpsc::Sender<String>) -> Result<(), gen::GenBodyError>
|
||||
{
|
||||
let string = {
|
||||
let chain = state.chain().read().await;
|
||||
if chain.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
match num {
|
||||
None => chain.generate_str(),
|
||||
Some(num) => (0..num).map(|_| chain.generate_str()).join("\n"),
|
||||
}
|
||||
};
|
||||
|
||||
debug!("Taking {:?} from {:?}" ,num, string);
|
||||
for sen in sanitise::Sentance::new_iter(&string).take(num.unwrap_or(1))
|
||||
{
|
||||
output.send(sen.to_owned()).await.map_err(|e| gen::GenBodyError(e.0))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -0,0 +1,41 @@
|
||||
//! Utils
|
||||
|
||||
pub trait NewCapacity: Sized
|
||||
{
|
||||
fn new() -> Self;
|
||||
fn with_capacity(cap: usize) -> Self;
|
||||
}
|
||||
|
||||
impl NewCapacity for String
|
||||
{
|
||||
fn new() -> Self
|
||||
{
|
||||
Self::new()
|
||||
}
|
||||
|
||||
fn with_capacity(cap: usize) -> Self
|
||||
{
|
||||
Self::with_capacity(cap)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> NewCapacity for Vec<T>
|
||||
{
|
||||
fn new() -> Self
|
||||
{
|
||||
Self::new()
|
||||
}
|
||||
|
||||
fn with_capacity(cap: usize) -> Self
|
||||
{
|
||||
Self::with_capacity(cap)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hint_cap<T: NewCapacity, I: Iterator>(iter: &I) -> T
|
||||
{
|
||||
match iter.size_hint() {
|
||||
(0, Some(0)) | (0, None) => T::new(),
|
||||
(_, Some(x)) | (x, _) => T::with_capacity(x)
|
||||
}
|
||||
}
|
Loading…
Reference in new issue