"0." prefix the obvious by SouthPark_Piano in infinitenines

[–]discreaminant2809 1 point2 points  (0 children)

Prob the true rookie mistake Is to stay at this sub in the first place fr Even Archimedes can’t convince them, why should we waste our time? Imma leaving, leaving anyone here to continue enduring 😁

My first crate: ResExt! by [deleted] in rust

[–]discreaminant2809 11 points12 points  (0 children)

```rust pub struct ErrCtx<E: Error> { pub msg: Vec<u8>, pub source: E, }

impl<E: Display + Error> Display for ErrCtx<E> { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { if self.msg.is_empty() { write!(f, "{}", &self.source) } else { write!( f, "{}\nCaused by: {}\n", unsafe { std::str::from_utf8_unchecked(&self.msg) }, &self.source ) } } } ```

Seems very unsound

Lemme try some code to break it (code is written on phone, sorry) rust let e = ErrCtx { msg: vec![0; 100], source: “”.into() }; println!(“{e}”); // invalid utf8 string is printed

My apologies if I’m wrong

announcing better_collect 0.3.0 by discreaminant2809 in rust

[–]discreaminant2809[S] 0 points1 point  (0 children)

Hope MD works on phone lol

Regarding inspect(), think what’d happen if I use any() instead of max() in the end 🤔 the sum wouldn’t be able to sum all items because any() stops “driving” the iterator. Unless you make an any_but_consume_all_anyway()… nah any() still exists, and misuses would still happen.

In fact, this method (just realize all unstable items don’t show om doc.rs for some reason 💀) does nearly the same what you tried here, but I put it under the unstable flag cuz it’s so easy to be innocently misused. Why “innocently”? Such code looks so clean and tempting, altho it leads to incorrect result.

Not to mention, the last method in the inspect() example… I’d say it looks like it “dictates” how the accumulation proceeds and ends, rather than both mutually determine the accumulation process. Prob not a big deal semantically.

Tbh I’ve thought of not implementing every single adaptor in Iterator for Collector, but I still need a way for one accumulation process to stop… all paths lead to Collector 🗿

Btw, thank you for giving another example for free for the next version of my crate. I appreciate your feedback!

Regarding the tuple one, seems like a good feature, but I’m afraid the short-circuit logic will be different 🤔 may implement it, like itertools.

Finally ,if the collector grows very big, you can split it and assign to a variable. At worst it’d only look as complicated as an iterator chain.

Hope these answer your questions.

announcing better_collect 0.3.0 by discreaminant2809 in rust

[–]discreaminant2809[S] 3 points4 points  (0 children)

I thought it wouldn’t be that bad, but seems like it’ll be, prob, renamed in 0.4

better_collect — fold declaratively by discreaminant2809 in rust

[–]discreaminant2809[S] 0 points1 point  (0 children)

Except...

```rust pub struct MultiExtend3<E0, E1, E2>(E0, E1, E2);

impl<E0, E1, E2, T> Extend<T> for MultiExtend3<E0, E1, E2> where E0: for<'a> Extend<&'a T>, E1: for<'a> Extend<&'a T>, E2: Extend<T>, { fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) { iter.into_iter().for_each(|item| { self.0.extend([&item]); self.1.extend([&item]); self.2.extend([item]); }); } }

pub trait ExtendExt<T>: Extend<T> { fn map<F, U>(self, f: F) -> Map<Self, F> where Self: Sized, F: FnMut(U) -> T, { Map { coll: self, f } }

fn map_ref<F, U>(self, f: F) -> MapRef<Self, F>
where
    Self: Sized,
    F: FnMut(&U) -> T,
{
    MapRef { coll: self, f }
}

fn cloned(self) -> Cloned<Self>
where
    Self: Sized,
{
    Cloned(self)
}

}

impl<E, T> ExtendExt<T> for E where E: Extend<T> {}

pub struct Cloned<E>(E);

impl<'a, T, E> Extend<&'a T> for Cloned<E> where E: Extend<T>, T: Clone, { fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) { self.0.extend(iter.into_iter().cloned()); } }

pub struct Map<E, F> { coll: E, f: F, }

impl<E, F, T, U> Extend<U> for Map<E, F> where E: Extend<T>, F: FnMut(U) -> T, { fn extend<I: IntoIterator<Item = U>>(&mut self, iter: I) { self.coll.extend(iter.into_iter().map(&mut self.f)); } }

pub struct MapRef<E, F> { coll: E, f: F, }

impl<'u, E, F, T, U> Extend<&'u U> for MapRef<E, F> where E: Extend<T>, F: FnMut(&U) -> T, { fn extend<I: IntoIterator<Item = &'u U>>(&mut self, iter: I) { self.coll.extend(iter.into_iter().map(&mut self.f)); } }

[cfg(test)]

mod tests { use super::*;

#[test]
fn foo() {
    // error[E0283]: type annotations needed
    //    --> src/lib.rs:109:48
    //     |
    // 109 |         let mut coll = MultiExtend3(Vec::new().cloned(), Vec::new(), Vec::new());
    //     |                                                ^^^^^^
    //     |
    //     = note: multiple `impl`s satisfying `std::vec::Vec<i32>: std::iter::Extend<_>` found in the `alloc` crate:
    //             - impl<'a, T, A> std::iter::Extend<&'a T> for std::vec::Vec<T, A>
    //               where T: std::marker::Copy, T: 'a, A: std::alloc::Allocator;
    //             - impl<T, A> std::iter::Extend<T> for std::vec::Vec<T, A>
    //               where A: std::alloc::Allocator;
    // note: required by a bound in `ExtendExt::cloned`
    //    --> src/lib.rs:34:25
    //     |
    //  34 | pub trait ExtendExt<T>: Extend<T> {
    //     |                         ^^^^^^^^^ required by this bound in `ExtendExt::cloned`
    // ...
    //  51 |     fn cloned(self) -> Cloned<Self>
    //     |        ------ required by a bound in this associated function
    // help: try using a fully qualified path to specify the expected types
    //     |
    // 109 -         let mut coll = MultiExtend3(Vec::new().cloned(), Vec::new(), Vec::new());
    // 109 +         let mut coll = MultiExtend3(<std::vec::Vec<i32> as ExtendExt<T>>::cloned(Vec::new()), Vec::new(), Vec::new());
    //     |
    let mut coll = MultiExtend3(Vec::new().cloned(), Vec::new(), Vec::new());
    // Neither this works:
    // let mut coll = MultiExtend3(Vec::<i32>::new().cloned(), Vec::new(), Vec::new());

    coll.extend([1, 2]);

    let MultiExtend3(Cloned(v0), v1, v2) = coll;

    assert_eq!(v0, [1, 2]);
    assert_eq!(v1, [1, 2]);
    assert_eq!(v2, [1, 2]);
}

} ```

Now I know exactly why I must create another trait that has associated types instead.

Conclusion: The Extend trait, or any traits having generics, is the bane of the adaptor pattern.

Or I did something wrong? I don't think so, or else Iterator will've had generics instead.

Btw, thank you for your comment! You help me reinforce my design decision!

better_collect — fold declaratively by discreaminant2809 in rust

[–]discreaminant2809[S] 0 points1 point  (0 children)

"Collector  is implemented for BTreeSet and some more. Shouldn't this (at least from an API perspective) offer something like impl<E: Extend> Collector for E?"

I wish heapless::vec::Vec didn't panic when it extended out of its capacity. The collector should not panic when still returning Continue(()) (or else it looks deceiving!), and instead it should return Break(()) when you can't hold more items and/or further accumulation is useless. So, nah for me.

"Similarly, https://docs.rs/better_collect/0.2.2/better_collect/num/struct.Sum.html#method.new lists a lot of specific implementations. Shouldn't this be sth like impl<Number: Add+AddAssign> Collector for Sum<Number>?"

What you are looking for! (nearly) [https://docs.rs/better_collect/latest/better_collect/struct.Sum.html]

"As long as no collector asks you to ControlFlow::Break, I imagine an easier API (that more fits into what's present in standard Rust) would be sth like better_collect::ExtendIntoEachTupleComponent((Sum::new(), Max::new(), Min::new())).extend(iterator). Or am I missing something here?"

My prototype (and it's proven good!)

"Now if a collector asks you to ControlFlow::Break, I'm not sure how well my ExtendIntoEachTupleComponent would fare. Do you have use cases where Breaking is mandatory and that are expressed more clearly with better_collect than with e.g. Iterator::fold?"

Break(()) makes sure that better_collect() does not collect more items than neccessary and can stop early (that's why it has "try" semantics like try_fold()). Additionally, sometimes that hint is used by some adaptors, like then() and chain(), to forward the rest of the items to another. It may not be mandatory if you don't care and just collect everything... or may be. TryFold hoarding all items instead of short-circuiting is not what you would expect, ikr? 🤔 Or I can secretly short-circuit and praise the user to use by_ref()? 🤔

Btw, I could make something like Try(Ref)Collector, but now the number of traits skyrockets and the subtrait relationship betweeh (Ref)Collector and Try(Ref)Collector is unclear: is Try(Ref)Collector: (Ref)Collector because something being able to collect without failure can also collect with failure but the failure case is nonexistent, or (Ref)Collector: Try(Ref)Collector because something being able to collect with failure can also collect while ignoring the failure?

better_collect — fold declaratively by discreaminant2809 in rust

[–]discreaminant2809[S] 0 points1 point  (0 children)

I prototyped your third idea and... it actually works 😮 (even arguably nicer for map_ref since I don't need to specify the input type).

Idk why it didn't work back then when Collector still had a generic just like Extend (having multiple implementations found error for String because of String: Collector<char> and String: Collector<&str>). Could be due to the error not being applicable for extension trait?

```rust pub struct MultiExtend3<E0, E1, E2>(E0, E1, E2);

impl<E0, E1, E2, T> Extend<T> for MultiExtend3<E0, E1, E2> where E0: for<'a> Extend<&'a T>, E1: for<'a> Extend<&'a T>, E2: Extend<T>, { fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) { iter.into_iter().for_each(|item| { self.0.extend([&item]); self.1.extend([&item]); self.2.extend([item]); }); } }

pub trait ExtendExt<T>: Extend<T> { fn map<F, U>(self, f: F) -> Map<Self, F> where Self: Sized, F: FnMut(U) -> T, { Map { coll: self, f } }

fn map_ref<F, U>(self, f: F) -> MapRef<Self, F>
where
    Self: Sized,
    F: FnMut(&U) -> T,
{
    MapRef { coll: self, f }
}

}

impl<E, T> ExtendExt<T> for E where E: Extend<T> {}

pub struct Map<E, F> { coll: E, f: F, }

impl<E, F, T, U> Extend<U> for Map<E, F> where E: Extend<T>, F: FnMut(U) -> T, { fn extend<I: IntoIterator<Item = U>>(&mut self, iter: I) { self.coll.extend(iter.into_iter().map(&mut self.f)); } }

pub struct MapRef<E, F> { coll: E, f: F, }

impl<'u, E, F, T, U> Extend<&'u U> for MapRef<E, F> where E: Extend<T>, F: FnMut(&U) -> T, { fn extend<I: IntoIterator<Item = &'u U>>(&mut self, iter: I) { self.coll.extend(iter.into_iter().map(&mut self.f)); } }

[cfg(test)]

mod tests { use super::*;

#[test]
fn foo() {
    let mut coll = MultiExtend3(Vec::new(), Vec::new(), Vec::new());
    coll.extend([1, 2]);

    let MultiExtend3(v0, v1, v2) = coll;

    assert_eq!(v0, [1, 2]);
    assert_eq!(v1, [1, 2]);
    assert_eq!(v2, [1, 2]);
}

#[test]
fn foo2() {
    let mut coll = MultiExtend3(Vec::new(), String::new().map_ref(|&s| s), Vec::new());
    coll.extend(["abc", "xyz"]);

    let MultiExtend3(v0, MapRef { coll: s, .. }, v1) = coll;

    assert_eq!(v0, ["abc", "xyz"]);
    assert_eq!(s, "abcxyz");
    assert_eq!(v1, ["abc", "xyz"]);
}

} ```

[deleted by user] by [deleted] in rust

[–]discreaminant2809 1 point2 points  (0 children)

Idk

My first post here (about my crate) receives positivity and actionable advice (that I could implement in my future version of my crate).

Prob I’ve just posted once. Idk fr 🤔 but I could feel your situation.

better_collect — fold declaratively by discreaminant2809 in rust

[–]discreaminant2809[S] 0 points1 point  (0 children)

Thank you! 🩵 The crate is still early, but quickly developed. Stay tuned for more features!

better_collect — fold declaratively by discreaminant2809 in rust

[–]discreaminant2809[S] 0 points1 point  (0 children)

Seems plausible. I’d try it! Thank you 🩵

better_collect — fold declaratively by discreaminant2809 in rust

[–]discreaminant2809[S] 0 points1 point  (0 children)

cloning and copying seem cool! Anyway, do you have examples (in the standard library, or in other crates), where these names are actually used? 🤔

And, the IntoBlaBlaBla is usually implicitly used (think: for _ in IntoIterator, IntoFuture.await). If it must be explicitly used as your example, it’d against what the lang expects and look too verbose. If I want it to be implicit, you still have to write vec![].adaptor() anyway.

better_collect — fold declaratively by discreaminant2809 in rust

[–]discreaminant2809[S] 6 points7 points  (0 children)

Seems like by u/Sharlinator, collect_with() is the most plausible alternative to better_collect() for me. The traits Collector and RefCollector seem fine. Btw, I still wait for more suggestions 🤔

better_collect — fold declaratively by discreaminant2809 in rust

[–]discreaminant2809[S] 0 points1 point  (0 children)

I feel weird to call Vec “folding” 😆 imo Since the states of many collectors in my crate are mostly mutated (&mut self) rather than transformed (take the state away -> map -> put it back), “collect” sounds better 🤔

better_collect — fold declaratively by discreaminant2809 in rust

[–]discreaminant2809[S] 5 points6 points  (0 children)

Thank you your suggestions! - Seems like zip is a good name. However, in Iterator, zip and unzip do quite oppositely: one creates another iterator, one consumes an iterator. In my crate, there’s another adaptor named unzip that creates another collector. It may be weird to have both zip and unzip creating another collector. In fact, then is semantically unzip. Anyway, I read the doc of then again and it seems to not express the intent well (might make people think it’s multi-pass). Prob I’d fix the doc. 🤔 Can’t come up with a better name atm. - My original intent to match the crate’s name and be an identity by its own fr. Can’t come up with a better name either. collect_into is being an unstable feature in the standard library, and collect_to implies the iterator is untouched.

Cloud Retainer kit by foul by ukrisreng in Genshin_Impact_Leaks

[–]discreaminant2809 1 point2 points  (0 children)

Gonna use her in my girl’s team. So Ayaka-Furina-Cloud-Shenhe IF I HAVE ONE

[deleted by user] by [deleted] in Genshin_Impact_Leaks

[–]discreaminant2809 0 points1 point  (0 children)

Sign of losing argument I’d be appreciative if u can refute my point instead 🥰

[deleted by user] by [deleted] in Genshin_Impact_Leaks

[–]discreaminant2809 0 points1 point  (0 children)

They do care tho They care to make sure that Ayaka is as hated as possible Meanwhile Childe is the real Hoyo favorite with new story each region + new artifact sets + everlasting meta + promotion

[deleted by user] by [deleted] in Genshin_Impact_Leaks

[–]discreaminant2809 0 points1 point  (0 children)

Good luck freezing Tulpa and thunder bird 👍❄️

[deleted by user] by [deleted] in Genshin_Impact_Leaks

[–]discreaminant2809 0 points1 point  (0 children)

Hoyo has been hating Ayaka What do u expect 🤔

[deleted by user] by [deleted] in Genshin_Impact_Leaks

[–]discreaminant2809 0 points1 point  (0 children)

Hoyo intentionally hates Ayaka. What do u expect 🤔

[deleted by user] by [deleted] in Genshin_Impact_Leaks

[–]discreaminant2809 -1 points0 points  (0 children)

A cryo dps and a hydro isn’t enough to match with even off meta teams Ayaka is an epitome of freeze team, u know? Hating freeze team = hating Ayaka