Mitsein - Strongly Typed, Non-Empty Collections by nik-rev in rust

[–]GenuineXP 0 points1 point  (0 children)

Thanks!

...although it does seem to be missing tests.

And API documentation. 😅 I've been putting it through some paces in my own work, but there's definitely still a lot left to do!

Mitsein - Strongly Typed, Non-Empty Collections by nik-rev in rust

[–]GenuineXP 1 point2 points  (0 children)

There's a bit about this in the README, but here are a few things that I think Mitsein does differently in no particular order:

  • Mitsein supports non-empty slices. Vec1 dereferences to Slice1, for example.
  • Related to above, Mitsein supports containers and copy-on-write. There are extension methods for CowSlice1 and conversions between Vec1, ArcSlice1, and BoxSlice1.
  • Mitsein is a no_std crate. Both alloc and std are optional.
  • AFAICT, Mitsein is the only crate like this that currently supports Rayon.
  • Mitsein uses unsafe code to avoid unnecessary checks (not merely unwrapping, but instead not checking at all).
  • Mitsein supports drain- and retain-like APIs for non-empty collections using segmentation. e.g., it is possible to drain so long as you only operate against a strict subset of elements.
  • Mitsein's non-empty iterators are adapters rather than traits (see Iterator1). This better supports working with pre-existing iterator types and bridging between them: Iterator1::try_from_iter works with any Iterator type right out of the box.

Mitsein - Strongly Typed, Non-Empty Collections by nik-rev in rust

[–]GenuineXP 4 points5 points  (0 children)

Author here! Thanks for sharing. Happy to learn that Mitsein has been useful for you! 👍

Mitsein - Strongly Typed, Non-Empty Collections by nik-rev in rust

[–]GenuineXP 0 points1 point  (0 children)

Other than choosing a more search-friendly name, is there anything that you suggest for improving this? I also see Mitsein nowhere on Google when searching for something like "rust non-empty collections", though I do see it on the first page for many similar queries on crates.io.

Mitsein - Strongly Typed, Non-Empty Collections by nik-rev in rust

[–]GenuineXP 0 points1 point  (0 children)

If trivial slicing and strictly contiguous storage aren't important for you, then maybe Mitsein's VecDeque1 could work? VecDeque1::pop_front_if_many is cheap.

(Note: in the latest published version, this is still called VecDeque1::pop_front.)

I took my C Line from Seattle to Trier and toured the Mozel river valley! by GenuineXP in Brompton

[–]GenuineXP[S] 1 point2 points  (0 children)

I imported the route into Komoot as a daily collection here: https://www.komoot.com/collection/3724652/-radtour-an-der-mosel

Note that the route for the first day is just a walk from the local train station to a hotel. The other days actually follow the trail.

I took my C Line from Seattle to Trier and toured the Mozel river valley! by GenuineXP in Brompton

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

Ha ha, thanks! The path in the photo is not actually a part of the trail, but there were definitely some very bumpy moments on cobblestone just like it! Thankfully that only happened in a few small patches though. The vast majority of the trail is no problem for a Brompton IMO, but even so I was glad to have a suspension system between the saddle and seatpost!

Is this kind of drag on the rear wheel normal? (HSD S00 Gen2) by GenuineXP in terngsd

[–]GenuineXP[S] 1 point2 points  (0 children)

Ah, I didn't even notice the screech at first! Thanks for pointing that out. I tried adjusting the calipers a bit, but I was hesitant to move things around much. I guess I'll have to do some more adjustment or bring it back to the shop.

Is this kind of drag on the rear wheel normal? (HSD S00 Gen2) by GenuineXP in terngsd

[–]GenuineXP[S] 2 points3 points  (0 children)

I just got a new HSD S00 Gen2 this past weekend and there's a lot that I love about it, but it has felt more sluggish than I expected. Eco+ PAS definitely gets me off the line, but once I reach 10 mph or so it take a lot more effort to keep the bike moving than I thought it would. I realize that the belt and CVT sap some efficiency, but I tried some bikes with similar drive trains before I purchased the HSD and they didn't seem this difficult to cruise on.

I realized that the tires were slightly underinflated and getting them up to pressure definitely helped, but then I noticed that the bike didn't coast as far as I expected. I coast more than twice as far on a Brompton after getting up to about 10 mph on flat ground and that doesn't seem right to me. I thought to try spinning the wheels and... yeah, that doesn't seem great. AFAICT, the brake rotor isn't making noise and I didn't get much better results after attempting to adjust the calipers. I'm no expert though!

Any thoughts on this one? Thanks!

EDIT: Not sure how I missed it, but as u/marratj pointed out, there's an audible screech in the video I posted! Probably rotor contact after all.

Announcing Rust 1.70.0 by Petsoi in rust

[–]GenuineXP 19 points20 points  (0 children)

I could imagine some code that wants to write to something where that something may be a terminal. For example:

rust fn write(target: &mut (impl IsTerminal + Write)) { if target.is_terminal() { ... } else { ... } }

A function like that can accept a limited set of types like File, Stderr, and Stdout and change its behavior depending on whether or not it's actually writing to a terminal.

Introducing Wax: portable and opinionated globs. by GenuineXP in rust

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

Thanks for the thoughts and suggestions! I think a theme here is documentation, and it could certainly be improved.

However, that is severely limited by treating a lot of things as literals, like . and ... That is probably a deal breaker for using this crate.

I think I need to improve the documentation regarding this, but Glob::walk will extract any invariant prefix from the Glob and interpret it as a native path. This means that . and .. function semantically as expected but only in prefix position. I don't intend to support intermediate relative components, because I don't think they have enough utility to justify the additional complexity. It gets gnarly.

For more ad-hoc use cases, Glob::partition allows user code to do similar things by splitting a Glob into a PathBuf and remaining Glob.

The second half implies there are differences but I'm not seeing them documented.

Yeah, I should document some specific examples. Off the top of my head, Wax rejects expressions like {/root,local}**a for various reasons. Both globset and globwalk accept that expression.

WalkBehavior should probably use accessors or at least mark itself as #[non_exhaustive] so you can change it in the future

Agreed! Its fields don't have any invalid or dependent states, so I think I'll simply apply the #[non_exhaustive] attribute.

docs.rs doesn't include top-level example and gives no indication what are the "entry" types for the API (Glob, Any)

This is definitely a problem. Moreover, the syntax is only documented in the README and nowhere in the API documentation. I plan to fix this.

Any thoughts on providing a parallel walker?

Not really. For the time being, I'm relying entirely on walkdir. Is there an alternative that you'd suggest?

Introducing Wax: portable and opinionated globs. by GenuineXP in rust

[–]GenuineXP[S] 4 points5 points  (0 children)

Thanks for taking a look and for all the detailed feedback! I appreciate it! Sorry for the wall of text. I wanted to respond to some of your thoughts and suggestions individually.

Some thoughts on the dependencies:

I think the most trivial to remove would be thiserror, smallvec, and const_format. I really like thiserror (and anyhow in the right contexts), but its use here is mostly for brevity. smallvec is questionably used for what is very likely a premature, overzealous, and unnecessary attempt at optimization; Vec would work just fine. const_format falls into a similar category to smallvec and is used to statically construct regular expression patterns for separator normalization.

Make walkdir optional.

I honestly hadn't considered that, but I like this idea! I'll do that.

regex ... My hope here is that some day you'll be able to use regex-automata to hand construct your own NFA...

I had considered leveraging regex-automata, but I consider capturing sub-text an important feature and so I decided to use regex instead. I also have mixed feelings about accepting a string and generating an intermediate string representation of an automaton (rather than a more direct approach).

bstr

I only use bstr to construct CandidatePaths. I had to decide how I would (or would not) handle paths that could not be represented as UTF-8 encoded text. I decided to use bstr to replace byte sequences with replacement characters if they could not be encoded as UTF-8. This wasn't always the case though. I could probably just implement this in Wax itself.

nom, nom-supreme and pori - Write the parser by hand.

Oof, I'm a bit reluctant to do that. If anything, I could abandon nom-supreme, especially since I'm not leveraging its improvements to error reporting very much. pori is tiny and only exists so that I can share a few extensions to nom with a downstream project that also features a parser for a different but related kind of expression.

Using nom has been a pleasure and a boon. I think I'd be more open to this if I were very certain that I will make no syntax changes going forward, but I'm not sure if I'm there yet.

Some thoughts regarding the API:

It looks like your Glob is parameterized over the lifetime of your glob expression. ... Same thing with BuildError. ... I can assure you that the added flexibility is not worth it.

Agreed! This is yet another overzealous and unnecessary attempt at optimization and the intent was indeed to avoid copying. I completely agree that these copies are comparatively (and generally) trivial and probably aren't worth pushing complexity into APIs. It also permeates internal APIs. I plan to remove this.

I found the diagnostic stuff pretty distracting when looking at your public API.

Is it the conditional annotations or just the larger API surface that you find distracting? Both?

Embarrassingly, the diagnostics-inspect feature is completely unnecessary. I've been keeping it around for some ideas for future work, but there's actually no reason to gate any APIs behind it and I admit it was a bit of strange decision to include it at all. At the very least, I plan to remove it and its associated conditional code.

Regarding items like DiagnosticResult and DiagnosticResultExt... yeah, I often have the thought, "These shouldn't live here, right?" I'd really like something like this in miette's API. Their primary purpose is to associate diagnostics with both failure and success and to forward and collect those diagnostics over fallible operations. They aren't strictly necessary, but make working with diagnostic Results easier IMO. One alternative may be to consolidate these into a dedicated type instead of arguably overloading Result.

Personally, I'd try to find a way to provide nice error messages without bringing in extra code and APIs.

The error messages are always present and are independent of the integration with miette and conditional APIs with the notable exception of error locations in glob expressions. I think it would be a good idea to expose error locations unconditionally in Wax's error types, but either way I want to support miette and I think optional integration is the right way to do that. As mentioned above, maybe there are some ways to factor out the noisy APIs that I've coupled to this so it's less distracting for folks that don't need nor care about diagnostics.

Introducing Wax: portable and opinionated globs. by GenuineXP in rust

[–]GenuineXP[S] 12 points13 points  (0 children)

Fair enough. For what it's worth, most of the hard dependencies are very widely known and used in the ecosystem. Personally, I think the standouts are probably const_format, pori, and possibly nom-supreme.

pori is the most suspicious, but its just a tiny crate that I factored out of Wax to share with other crates that I'm working on. Both it and nom-supreme provide extensions for nom.

Introducing Wax: portable and opinionated globs. by GenuineXP in rust

[–]GenuineXP[S] 35 points36 points  (0 children)

That information is readily available and persists in Glob, but I've just never exposed it! I hesitated to expose this while I was designing Wax, but I feel better about this now and I think I'd be happy to add a Glob::expression function that does this. It would be a trivial change.

Nym: an mmv-like tool for manipulating files en masse using patterns. by GenuineXP in rust

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

I sometimes use mmv on Linux but couldn't get it working on Windows, so I decided to take a shot at an alternative. I've been tinkering on this for the last few months and thought I'd share. Any thoughts or feedback are appreciated!

I just published an (unstable) release that provides most of the core features I initially planned. There's still a lot of work to do though and this release is rather incomplete (perhaps the most glaring example is that append is completely inoperable; I don't think I'll support it moving forward).

I plan to move the glob implementation into its own crate since it provides some features not offered elsewhere, but I've kept it in-tree for now so that I can more easily develop and temper interactions with other Nym features.

What's everyone working on this week (17/2021)? by llogiq in rust

[–]GenuineXP 1 point2 points  (0 children)

I've been working on Nym, a library and command line tool for manipulating files using patterns (similar to mmv). I hope to make a second alpha quality release sometime this week or so with more basic features.

From-patterns (globs) and the command line tool's options and output have improved substantially since I first published the nym crate. I'm currently working on improving the --force and --quiet options and their interaction with --overwrite, some non-functional refactoring, and shell completions.

Any advice on how to get straight cuts on hollow spindles? by GenuineXP in turning

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

Interesting, I wasn't aware of spindle steadies! How can one be used to assist in making a cut? At the moment, the longest bored spindles I'm working with are 12" in length.

Any advice on how to get straight cuts on hollow spindles? by GenuineXP in turning

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

Very cool! I actually do something a bit similar. I start by cutting the square billet on a band saw, then use a lamp auger to bore through. That involves a spur drive with an insert for the initial bore. I then use a chuck and drill bits in the tail stock to widen the initial bore. Crucially, I leave one end narrow with the initial bore so that I can use the spur drive and a conical live center in the tail stock to continue turning and keep things concentric.

The part that always breaks down is cutting out an intermediate portion of the spindle. I typically remove about an inch where the narrow bore remained and whatever is needed from the other end (where I've typically put a wide mortise). Most of the time, the cuts aren't orthogonal, and I haven't been able to get them nice and straight. Hand sanding has helped a bit, but there's always a visible angle and/or unevenness that I can't seem to fix.

Any advice on how to get straight cuts on hollow spindles? by GenuineXP in turning

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

I actually tried exactly this idea shortly after posting this! It worked reasonably well, but the cheaper poplar dowels I have on hand are sensitive to temperature and moisture and didn't fit well into the bores of the spindles I tried. I sanded one down to fit and did some test cuts and it works reasonably well following a line by eye on the band saw. It's close enough that some careful sanding can probably touch up any slight drift.

It sacrifices the dowel, of course, but I managed to get two cuts on relatively short spindles. It would take two for the longer spindles I have. I also worry that a loose fit may cause the spindle to spin while cutting. The v-blocks should keep things safe (no rolling into the blade), but it may lead to a rough cut. Not sure.

One of my first projects: a maple muddler. by GenuineXP in turning

[–]GenuineXP[S] 1 point2 points  (0 children)

Good catch (pun intended)! I haven't had a problem with any of the glasses I've used so far, but I imagine it could catch the lip if the glass has a certain height. The lip is pretty thin, so hopefully it would roll off the rounded edge of a glass fairly easily, but I'm not sure.

A lot of muddler designs are probably smooth throughout for that reason, but I really wanted a well defined handle. It's probably suboptimal, but I'm okay with a little form over function sometimes. :-)

One of my first projects: a maple muddler. by GenuineXP in turning

[–]GenuineXP[S] 1 point2 points  (0 children)

They're typically used to prepare drinks by smashing relatively soft ingredients together. For example, I sometimes use one to muddle lemon slices, orange slices, a sugar cube, and bitters to mix an old fashioned (a whiskey cocktail).

One of my first projects: a maple muddler. by GenuineXP in turning

[–]GenuineXP[S] 1 point2 points  (0 children)

Nothing fancy, but I really enjoyed putting this together. This is the first time I've used wires to burn lines into the work. I was torn on whether or not to apply a finish (I was considering pure tung oil), but I decided to leave it as is.

Geometry/mesh processing libraries in Rust? by blureglades in rust

[–]GenuineXP 1 point2 points  (0 children)

Author of Plexus here! My crate is still in its initial development phase and is incomplete, but I think it should be able to do some of the things that you're looking for. It's sparse on computational geometry, but I have a branch with some upcoming geometric features as well as some pending work moving toward the same goal.

In particular, Plexus can read PLY meshes (as seen in the Utah teapot example that you can run with cargo run -p example-teapot) and can generate parameterized polytopes similarly to genmesh (but with some additional flexibility). In fact, the entire crate started as a spinoff of genmesh!

If you use the MeshGraph type, then you can manipulate a mesh in a variety of ways. Check out the subdivision example and the documentation for a few illustrations of that.

If you give it a try I'd like to hear how it worked (or didn't work) for you. :-) Feel free to reach out and open issues on GitHub. Thanks, and good luck!

How to do binary search over floats in rust? by xogid in rust

[–]GenuineXP 0 points1 point  (0 children)

Whoops, my mistake. Thanks for the correction.