Your phone and your laptop both shipped with a notes app that does exactly this. The only reason to leave is that the built-in ones sync badly across Android and Windows specifically, which happens to be your case. That's the one real constraint in your post and it's the thing that should drive the choice, not features, not philosophy.
Nadia Feld
@grepwitch
I spend most of my day in a terminal untangling other people's shell scripts. Ask me about awk, sed, and why your cron job runs at a different time than you think.
33 credit Contributor
- From answers
- 0
- From questions
- 33
The four-plugin rule is real. Mine are a calendar, a task query, one editor tweak and one export helper, stable for two years, and I couldn't tell you what the other fifteen did.
Slight disagreement with the crowd: the channel design gets much more attractive if your writes ever need to be conditional on a read, like 'increment unless over the limit'. With a lock you either take a write lock for every check or you race. Rate limiting is exactly the kind of thing that tends to grow that requirement in month three.
Six years and the only complaint is mobile. That's about the most useful data point in this whole thread.
Two and a half years on an open source local-first one. Nearly left when a version bump changed the file layout under me. Stayed because the files were still text and I could fix it myself in twenty minutes, which is the entire argument for local-first compressed into one sentence.
Also worth diffing the rendered HTML against a copy from the Wayback Machine on a date before the drop. 'We didn't touch the page' is true surprisingly often at the CMS level and false at the template level.
The unwrap bugs me slightly. if let Some(last) = events.last_mut() { ... } else { events.push(item) } doesn't work here because of the else branch, so an alternative is to match on should_merge and use events.last_mut().expect("checked above") so the invariant is at least documented.
Another shape that fits well when the decision needs more than a bool: pull whatever you need out of the last element as owned copies of the small fields, not the whole struct. If the merge decision depends on a timestamp and an id, copy those two, drop the borrow and carry on. You said the struct is 200 bytes but the decision probably needs 16.
Worth checking whether the new platform serves those pages client side. Fetch one with curl -s <url> | wc -c and then look at what's actually in the HTML. I've seen platforms where the indexed pages happen to be prerendered and the rest are an empty shell with a JS bundle, and Search Console's inspection tool renders it fine so you never notice.
One thing nobody has mentioned. Cross-trainers are usually much flatter than road running shoes, so if you've been running in something with almost no heel raise, that is a genuine change in how load goes through the calf and knee, entirely separate from cushioning.
The test is one question: can you open a single note in a text editor with the app uninstalled? Yes, you're free. No, you're a tenant.
Reading it bottom to top is genuinely the trick with these. The last few lines name your type and your await, everything above is the machinery explaining why it cares.
Order of operations matters more than tooling. Strip hashes from filenames first, then rewrite links, then move images, then delete nothing for six months. People do it in the other order and end up with a rewrite pass pointing at files they've already renamed, which is how a two-day job becomes a two-week job.
Everyone is. A hierarchy is a thing you feel good about maintaining and almost never use to find anything.
If you go with 8, redirect each old URL to the specific section anchor on the new page rather than dumping all 40 at the same top-level URL. Takes an extra hour and keeps the mapping meaningful if you ever need to unpick it.
Box<dyn Iterator + '_> is a perfectly reasonable escape hatch when you have several branches returning different iterator types, and one heap allocation for an iterator you'll poll thousands of times is noise. I wouldn't feel like you gave up, I'd feel like you shipped.
Arena patterns aren't dead in Rust, they just become indices into a Vec instead of pointers. Once you make that swap a lot of C-shaped designs work fine.
Two months, and the concept was that a reference is a borrow of a specific thing for a specific window, not a pointer that happens to be safe. Once I read every & as 'nobody may move or free this until I'm done', the rules stopped feeling arbitrary. Also, and I mean this kindly, coming from C is sometimes harder than coming from Python because you have a working mental model that is nearly right.