u/krdln
-
10points
krdln
krdln
Few times with sugru (this subreddit's fav recommendation) and now I'm on B7000 glue.
krdln
I've ordered few times from ifixit and I was happy with replacement. I think I had replaced it twice already – yeah, battery degrades after 2-3 years (:
https://www.ifixit.com/products/pebble-time-round-replacement-battery
krdln
On both plugs – cutting the fuse will disable the 5.1k resistors on the cc line. And that's needed because C-to-C cables (unless fancy ones with emarkers) shouldn't have any resistors and cc should just connect to cc on the other end on the cable. Btw, I really liked the hackaday series about USB C, eg. https://hackaday.com/2023/01/04/all-about-usb-c-resistors-and-emarkers/
And don't forget to actually put the 5th wire for the cc channel! (Even if you don't want PD or high speeds). Otherwise the devices won't be able to know which one is client and probably won't send any power.
Btw, 3 amps in 22 gauge wire is right at the spec limit, but I guess you'll be fine :)
I'd be happy to know if your cable worked!
krdln
Yeah, 110V is closer to 120 lemons, not 95.
krdln
A single atomic is always "ordered with respect to itself" (sorry, forgot what is a proper technical term for that). So if you only had a single atomic variable in your program and no other shared memory – you're good to use Relaxed for everything. What the Acquire and Release do is to establish the happen-before relation wrt to other memory locations (in case of spinlock that'd be the value protected by that spinlock)
krdln
For Parser you can do:
let cli: Cli = clap::Parser::parse();
krdln
As you said, the variable is fn(&'static str), so this is not really true:
After the assignment, the function would be able to accept
'areferences, which not necessarily live as long as a'staticreference.
The function will always be called only with 'static references – because that's the variable type. And that's ok, because the function you've assigned (fn(&'a str)) is prepared for any reference – including 'static ones.
krdln
By default shared things in Rust are read-only. You use internal mutability, when you need to modify a shared thing.
So anywhere you need to have a shared thing (&, Rc, Arc, static, captures of Fn), but you want to mutate it, you use internal mutability (cells, mutexes, atomics).
So you're basically right with:
when I have an immutable struct and i need some props to be mut
But it's rather
when I have a shared struct and i need some props to be mut
krdln
Box::new actually uses box!
krdln
This font gets double-bolded :D – Alfa Slab One is already bold, and then font-weight: 800 makes the browser "bold it even more" (fun fact: Rust blog also had the same issue). So instead of dimming the font-weight of titles, you should instead just tell the browser that Alfa Slab One is already bold:
@font-face {
font-family: 'Alfa Slab One';
font-style: normal;
font-weight: 800; ← change from 400
(setting weight 400 for title would also work, but would have a side-effect of disabling bold when fallback font is used)
krdln
You're probably trying to compile directly with rustc (judging by error message talking about main.rs, not src/main.rs). Try compiling with cargo build.
krdln
Hah! I've implemented almost the same thing a few years back! https://lib.rs/crates/fomat-macros Almost – fomat-macros is using () instead of {} and doesn't support some constructs (like let or closure escape hatch). Otherwise though, these libs should be compatible!
Some time ago I was wondering about having the macro to be drop-in replacement for std format, with idea to support both std syntax and "concatenated" syntax (used by fmtools/fomat-macros). But couldn't decide what to do on format!("{{") (which could mean "{" or "{{"). And newest "fstring syntax" make it even more ambiguous – how to interpret bare "{foo}" (interpolate or raw-string)? Failing to decide what to do with this ambiguity, I abandoned the idea of compat-mode / dual-mode... Perhaps you have some ideas on how to handle this?
Btw, after some tweaking I found it to be a nice perf improvement to call Display::fmt directly instead of going through format_args, perhaps you can try it.
krdln
Perhaps these rules will help you translate Go → Rust
- "I want to take a look"
[]Tparameter →&[T] - "I want to modify existing elements"
[]Tparameter →&mut [T] - "I have some data in a struct"
[]T→Vec<T> - "I'm building slice with
append"[]T→Vec<T>andpush.
Go's decision to handle all these cases with a single slice is a really weird decision – it's making the language simpler, yes, but it's easy to shoot yourself in a foot. Take a look at this example.
krdln
Haven't used diesel for a while, but judging by how it's done in postgres (SET metadata = metadata || var), I'd guess it'd be sth using diesel's equivalent of || – concat.
diesel::update(table).set(metadata.eq(
metadata.concat(
serde_json::json!( {"height": 180,"weight": 80} )
)
))
krdln
I think prost by default doesn't provide any such helpers on Value.
Check out https://lib.rs/crates/pbjson-types – looks like this is replacement crate for prost-types, but all types are serde-enabled, eg. https://docs.rs/pbjson-types/0.3.1/pbjson_types/struct.Value.html – you should be able to round-trip your struct via serde_json::Value to pbjson_types::Value (not sure if serde has a way for more direct "value-to-value" transcode, I'm only aware of Deserializer-to-Serializer transcoding).
But looks like you're using tonic, so not sure if you'd be able to replace prost-types via pbjson-types. But if that's not possible, worry not! You can add one rountrip – Message::encode pbjson_types::Value to bytes in protobuf format, and decode them as prost_types::Value :)
krdln
> Where the 1st element in the array is a string but the 2nd element is another nested array
If the the order is fixed, you can use a tuple
krdln
The niche range is actually a "wrapping" range 4..=0, so if you use the zero for None, the next layer (Option<Option<Size>>) will still have 4..=usize::MAX available (btw, it's most likely u8::MAX, not usize::MAX, Rust tries to keep the tag small)
krdln
Hm, in this case [first, ..] would match only 1-element lists (as [first, second, ..] covered 2+), so I guess you could as well remove it.
If you want to have fun with pattern matching you can also try:
match *s.split(';').collect::<Vec<_>>() {
[first, ""] => first.to_owned(), // handle trailing ; first
[first, second, ..] => format!("{} {}", second, first),
_ => s.to_owned(),
}
(though trim_end_matches is more readable imo)
krdln
Oh, I see now my mistake. Got so focused on "rev-propagation" that I've changed semantics from first two to last to elements. I'm pretty sure I've tested my solution, so I guess my eyes didn't see a difference between "tata titi" and "titi toto".
Yeah, you're right with take removing the double-endedness (which kinda makes sense, take is "unidirectional" adapter). So I guess there's no way around the "collect in the middle"...
But since you're collecting, you can reverse in place:
let mut first_two: Vec<&str> = s.split(';').take(2).collect();
first_two.reverse();
first_two.join(" ")
But that's uglier than the match solution, I guess.
krdln
The u/KhorneLordOfChaos solution looks the cleanest, but if you want something closer to what you've written, here's some things I've noticed:
edit: This whole comment below is wrong (I messed up when trying to remove collect and changed semantics from first two to last two elements))
You don't need to collect, when you're immediately folding, so instead of
s.split(';').collect::<Vec<_>>()[..2].iter().rfold(…)
you can do
s.split(';').rev().take(2).fold(…)
or
s.rsplit(';').take(2).fold(…)
The take should also take care of the no-; edge-case automatically.
Wrt. reversedir1 vs reversedir2, I'd go with 2, because it uses a single String buffer and version 1 creates a buffer on every iteration. This is perhaps not that important in your case, as the number of iteration is always 2, but if instead of 2 you had n, your algo would be quadratic (as every join would need to copy the whole string).
Here's how I'd approach it in the "iterator style":
s.rsplit(';').take(2).collect::<Vec<_>>().join(" ")
There's also a cool iterator method in nightly – intersperse, which (combined with ability to collect iterator of &strs into String) allows to avoid the intermediate collect:
s.rsplit(';').take(2).intersperse(" ").collect()
krdln
You're holding a lock while doing computation, so that only one thread can run at a time:
thread::spawn(move || {
let mut scores_table = scores_table.lock().unwrap();
scores_table.push(compute_scores(partition * partition_size, (partition + 1) * partition_size, voters, &weights_clone, quota));
})
Try locking only for call to push:
thread::spawn(move || {
let scores = compute_scores(partition * partition_size, (partition + 1) * partition_size, voters, &weights_clone, quota);
scores_table.lock().unwrap().push(scores);
})
krdln
Just tested it (playground) and the size of Option<Foo> is 24, which is exactly what you'd expect from niche optimization (since size of Foo is also 24).
Interesting, what exactly do you find to be incorrect here? For me, it reads perfectly normal, and commas seem to match the (a bit stream-of-consciousness-style, true) sentence structure correctly.
Perhaps "przyjaciółmi" would be less colloquial than "przyjaciele" and the last sentence is a bit weird, but that's everything I can see.