Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

Jo posted:

Speaking of traits, I've defined this type 'Skeleton' which I'm using as the "parent".

I'd like to define a 'load' method which takes a filename, since each different skeleton format (BVH, C3D, Blend, etc) will probably have its own skeleton struct.

Problem is the load() method should be returning a physical item, and I think for a trait object to be instanced it needs &self in all the methods. As a workaround, I'll probably get rid of the trait and just have a single skeleton type with a bunch of loaders. Still, it would be nice in future development to know how to do this.
I think you want
code:
trait Skeleton {
    fn load(filename : &String) -> Self;
    // ...
}
Your original code said that each implementation of Skeleton must define a function which can load a given file as any implementation of Skeleton whatsoever. Type parameters are provided by the caller, remember.

Ralith fucked around with this message at 06:05 on Nov 2, 2016

Adbot
ADBOT LOVES YOU

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
impl Trait is awesome, yeah, and a must for doing fancy combinator stuff without heap allocation, the possibility of which is one of the things that makes rust really stand out (although a single allocation per Future created across function boundaries isn't a big deal most of the time). The current implementation has some weird type inference limitations compared to Box<Trait>, but hopefully those will be addressed.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
In the spirit of thread bumps, lately I've been playing with error-chain. It seems like a real improvement over error handling in other languages. I replaced a bunch of "log a descriptive error message, then return an Err" code with "return an error with the descriptive message chained on to it" and my code became significantly more concise, and now I just have a single ten-line block in my main function that pretty-prints a log message for the entire logical chain of failures of anything that makes it that far unhandled, followed by a (runtime-optional) physical stack trace describing where the error came from. The macro for defining all the usual error boilerplate is pretty nice, too.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

Vanadium posted:

The ? thing is pretty cool and in general I'm a fan of the explicit Result<> returning, but actually creating a ~good~ error enum or w/e still seems like a lot of pain. Maybe I should just use Strings as errors.

Ralith posted:

In the spirit of thread bumps, lately I've been playing with error-chain. It seems like a real improvement over error handling in other languages. I replaced a bunch of "log a descriptive error message, then return an Err" code with "return an error with the descriptive message chained on to it" and my code became significantly more concise, and now I just have a single ten-line block in my main function that pretty-prints a log message for the entire logical chain of failures of anything that makes it that far unhandled, followed by a (runtime-optional) physical stack trace describing where the error came from. The macro for defining all the usual error boilerplate is pretty nice, too.
Still a thing.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

Vanadium posted:

Do you wanna post your code? I mean I've looked at a few of that sorta crate and I still end up getting a bit of a headache each time I think about what type of error I should return and how to structure them.

Sure. Here's an error module that just wraps multiple other error types:
Rust code:
use std::io;
use capnp;
use config;

error_chain! {
    foreign_links {
        io::Error, Io;
        capnp::Error, Capnp;
        config::Error, Config;
    }
}
Here's one that just has a few regular cases (in fact, this is (the basis of) what config::Error refers to in the above code):
Rust code:
error_chain! {
    errors {
        MissingKey(key: &'static str) {
            description("missing key")
            display("missing key \"{}\"", key)
        }
        MalformedValue(key: &'static str, reason: &'static str) {
            description("malformed value")
            display("malformed value for \"{}\": {}", key, reason)
        }
    }
}
You can use foreign_links and errors at the same time, if you like. There's also various other features but those are the biggies. This produces implementations for the usual traits and various fun methods, per the docs. For something a bit simpler, there's also quick-error, which might be more suited for cases where you specifically want to return a closed set of errors for matching on, rather than just indicate failure in debugging-friendly way.

Ralith fucked around with this message at 19:41 on Nov 13, 2016

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

Redmark posted:

Also holy poo poo emscripten/LLVM took forever to build. Is that typical for large C++ projects?
Yes, very. Rust's pretty bad about that too, really. Optimizing low-level code is computationally difficult.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
The author of error-chain has posted a nice introduction to the newest release which reveals that my use of foreign_links above was somewhat less than idiomatic and makes a better case for why it's worth using beyond saving boilerplate.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
You can chain_err any Result type if you have the symbols from a module containing an error_chain! invocation in scope. The method comes from a macro-generated ResultExt trait, and it returns the type of Result defined by that macro. For simple command-line tools, I often just have "error_chain! {}" at the top of the file so I can provide nice detailed information-preserving textual error messages everywhere.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
Ah, right. An easy solution would be to define a struct SDLError(String), impl Error for it, and map_err SDL results into that. Then go smack the SDL crate maintainers for unidiomatic error handling.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

MALE SHOEGAZE posted:

Do you have any good examples of command line tools written in rust?
The tools I've been writing recently wouldn't make much sense to share, but I hear ripgrep is pretty neat. If you're looking for examples of error-chain use specifically, the best I can do is suggest you page through the reverse dependency list. Maybe Xargo?

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

MALE SHOEGAZE posted:

So, I want to parse a protobuf result and then match over the possible return types, but I've got no idea how to to do it.

Protobuf types:

So, basically, I want to parse the protobuf message, and then match over the result, performing a dispatch depending on the type. But I'm clearly going about it the wrong way. Any clues?

I understand that it cant `parse_from_bytes` without a concrete type to return. I think I'm just using the protobuf library wrong but it has very little documentation so I'm just trying to follow the compiler to victory.

You can explicitly specify type parameters by calling a function with syntax like "parse_from_bytes::<MyMessageType>(m)". You may also get better results from inference once you've actually entered some cases that entail a specific concrete discriminant type.

Alternatively, you could switch to cap'n proto!

I assume you're aware that in real code you shouldn't call unwrap like that, and should instead define an error type which can clearly express/embed the cause of a failure, for example using error-chain.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

MALE SHOEGAZE posted:

boo! I tried that but I was doing parse_from_bytes<MyMessageType>(m). The parse errors probably should have clued me in.

And yeah, I'm still getting used to error handling, but I recognize that by just calling unwrap, I'm failing to handle errors.
The correct ::<>() is called the turbofish and now that you know its name you will never forget it.

gonadic io posted:

I'm pretty sure all Rust I've ever written contains ".unwrap() // TODO" and all haskell "fromJust x -- TODO"
The nice thing about error-chain and the ? operator is that it makes it really easy to implement basic error handling. Just foo.chain_err(|| "foo exploded")? everything and print all the guts of any error in your main function as shown in the quickstart example, and instead of a panic you get a graceful shutdown and a detailed backtrace. Upgrade from strings to matchable enum values as necessary.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

Asymmetrikon posted:

Filter is parameterized over a P: FnMut, which the compiler just represents as an anonymous closure, though. How do you express that kind of type concretely?
You'd have to implement a filtering iterator directly, with the predicate inlined into the implementation of next. Or restructure your code to avoid needing to do so, with generics and/or impl Trait.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

xtal posted:

Is there such a thing as a function composition or pipelining operator in Rust?
No operator, you're supposed to just use the concise closure syntax (e.g. |x| g(f(x))) for that if you really need it. You could write a composition function yourself, but it might be pretty annoying to try to use. A lot of things that work very cleanly in Haskell turn awkward and inconvenient with Rust because the language is much closer to the hardware. When half your functions/accessors take/return references and half don't thinks don't compose as tidily; auto-deref helps for regular first-order code but a naive compose operator wouldn't permit it to work.

Rust is, to its credit, not a great language for point-free shenanigans.

xtal posted:

I'm also interested in a macro to combine `fn` and `match` since all of my functions match anyway. Yes I come from Haskell and be glad you don't work with me.
I hardly ever see this idiom even in Haskell, when it comes to real-world code. Still, is there anything stopping you?

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

gonadic io posted:

Is there a way to generate an identifier inside a macro?
Given that rust macros are intended to be hygenic, what happens if you just give the struct a fixed identifier directly? If it works at all I imagine it'll be scoped to the macroexpansion.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

gonadic io posted:

I'm still not sure how this would affect how that block actually executes at run-time. Would all the type definitions and impls happen at compile-time so at run-time that's identical to just having the "Foo::new()" on its own?
As Mr. Glass says, placing type shenanigans inside blocks like that is purely a matter of name visibility. Rust has no notion of run-time definition of new types or trait impls.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

gonadic io posted:

I think impl trait is my favourite of the new features, just because it makes working with unboxed closures and iterators so much easier.
I don't think that's stable yet. Is it close?

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

TheCog posted:

I keep meaning to poke at rust but I don't have a good idea of what kinds of projects its well suited to. I've mostly only done webapps and web design like things, (ok and some automation scripts), are there any cool ideas for projects to build? I followed the tutorial in the docs a while back and built the guess checker, but that didn't really give me a good idea of what kinds of cool projects rust enables. Are there any really recommended tutorials or even just suggestions for things to build that people could recommend?
Build a raytracer! Raytracers are always fun and rust won't stop you from making it super fast.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

xtal posted:

I made a web app with Rocket and tbh it almost put me off Rust entirely. Probably 90% of it happens in macros, and Rust has one of the worst macro systems ever. Rust is going to need to address this at some point because the rigidity of the language makes you use macros and macros are worthless without homoiconicity
I don't have any experience with Rocket, but I hardly ever find myself reaching for macros when writing Rust. First-class functions, closures, traits, and polymorphism go a long way. Which is good, because macros 1.0 really do suck for any but the most trivial uses. Custom derive (stable, demonstrated nicely by serde) and the upcoming macros 2.0 (which gives you full-powered source-to-source transforms) are a lot nicer, fortunately.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
I want to be able to build EDSLs. My day job is C++ so I'm not exactly chafing at Rust's lack of expressiveness, but it'll be a good day when the next iteration is stabilized.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

MALE SHOEGAZE posted:

I'm playing with Rocket and Diesel -- they're the first real frameworks I've tried in rust (tokio is probably the largest library I've dealt with).

CodeGen and Macros are going to ruin this language.

http://docs.diesel.rs/diesel/macro.infer_table_from_schema.html

I'm flabbergasted that the compiler even makes this possible. I'm doubly flabbergasted that Diesel presents this in their tutorial as the way to generate their schema.
Wow. I'm a big fan of powerful tools even if they can be abused, but I do not understand people who think doing network shenanigans at compiletime is a good idea.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

MALE SHOEGAZE posted:

What concerns me is that rust made this incredibly easy. Yes, I was importing a crate called `_codegen`, which should have tipped me off, but beyond that it's just a macro. If this were enabled as part of a plugin, it would be a different story. Macros should not be able to do this, and now I'm going to have to be incredibly suspicious of every single macro I encounter because it could be doing network insanity at compile time. (I could be mistaken about some of this, I haven't actually figured out how this macro works yet).
"just a macro" can't do this. At a guess, the macro expands to a custom derive, which IIRC can run arbitrary code. Understanding what the macros you're using do is good practice regardless, of course.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
Procedural macros should generally be the exception, at least once declarative macros 2.0 lands. Hell, any kind of macros at all should be the rare exception, much less complicated ones. It's good to have escape hatches in a language, even if some people will always be tempted to treat the escape hatch more like a revolving door.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
GTK bindings don't care what IDE you use, but GTK on windows is pretty terrible. Rust doesn't really have any mature GUI stuff yet; you could try a web UI instead.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
Rust just got some really sweet enum memory layout optimizations. Highlights:
  • ignoring uninhabited variants (i.e. containing uninhabited fields), e.g.:
    • Option<!> is 0 bytes
    • Result<T, !> has the same size as T
  • using arbitrary niches, not just 0, to represent a data-less variant, e.g.:
    • Option<bool>, Option<Option<bool>>, Option<Ordering> are all 1 byte
    • Option<char> is 4 bytes
  • using a range of niches to represent multiple data-less variants, e.g.:
    • enum E { A(bool), B, C, D } is 1 byte

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
Relatedly, in that type of situation I like to do
code:
#[cfg(target_os = "windows")]
#[path="windows/mod.rs"]
mod platform;
#[cfg(target_os = "linux")]
#[path="linux/mod.rs"]
mod platform;
sort of thing, though you have to take considerable care to ensure the public APIs stay perfectly in sync if you don't enforce it with a trait or something.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

Walh Hara posted:

I already knew this, but this seems extremely dumb to me? Do I really need to fill the array with garbage (when I declare the variable) so I can replace this garbage in the for loop with the correct values? I was assuming there must a be better way.

Or should you just never use arrays when working with objects?
You can use mem::uninitialized() here if you want. It's unsafe because you have to ensure that drop never gets called on uninitialized values, but in cases like yours this is trivial. Of course, then you've introduced unsafe code just to perform an optimization that the compiler would have worked out on its own anyway.

tazjin posted:

I've spent the last two evenings looking at how to migrate a reasonably complex Rust system from error_chain to the new failure crate.

The system uses a bunch of external libraries (e.g. r2d2_postgres, rouille, serde of course, ...) and previously we used error_chain's foreign_links functionality to explicitly declare how all the possible errors that could occur would be converted into our error representations.

I considered that one of the major selling points of error handling in Rust: The compiler would be able to point out which foreign errors have not yet been "acknowledged" in the error handling strategy. It was still possible to then proceed to drop the errors on the floor, but dispatching different handling strategies on foreign & internal errors in the same way was trivial to do.

Now with failure everything gets shoved into a single, shared Error-type. Keeping information about what kind of error occured either requires littering the code with verbose .context(...) calls or using runtime reflection (:barf:) and - since almost every error is implicitly convertable to a failure - using ? now feels like working with a method that has throws Exception in its signature in Java.

To make things worse, errors from error_chain can actually not be converted to failures because they aren't Sync. This makes using libraries that have switched to failure somewhat painful from an error_chain based application.

This kind of "lets throw the types away!" dynlang bullshit should stay out of my Rust ecosystem :colbert:
Using failure doesn't mean you need to use failure::Error at all; that's expressly the lazy shortcut approach. Instead, you can define your own Error type, derive Fail for it, and implement From<ForeignError> for whatever errors you want to support. There's been some discussion on whether this exact pattern is actually a good idea, but it is certainly still supported.

Personally, I'm a fan of using .context(...) heavily because it lets you provide informative error messages; if your program does a bunch of IO, a simple "permission denied" error message can be incredibly unhelpful compared to, say, "couldn't open config file /foo/bar: permission denied". You don't necessarily need to scatter these all over your code, though, just at major boundaries.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

tazjin posted:

There's an example somewhere in the docs of failure in which .context(...) is used to add the string "file not found" to an IO-error, but it is in a situation where the error may just as well be something else - like "permission denied".

This leads to a similar issue as people encounter in Go: Layers of misleading error messages, concatenated together, because some programmer thought they could enumerate the possible errors at the point where they provided "context" in their head.
Huh? You're not enumerating anything, you're providing context. That is why the method is called "context". The inner error is still there to be inspected and displayed in turn. If your error messages are misleading, fix them.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

HappyHippo posted:

Ok between that and the documentation I think I understand. Thanks
You can also use cargo vendor on an external machine then bring the results into the protected network, if you like.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

Dominoes posted:

Hey dudes. How do you enter values in scientific notation?

Rust code:
const ELECTRON_MASS: f64 = 9.109390 * (10.).powi(-31);
The syntax is the same as in most programming languages, e.g. 9.109390e-31.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

Linear Zoetrope posted:

Basically, Rust does untyped infinite-precision arithmetic on literals, but this is limited to the built in operators (+, -, *, /, and for ints, %, |, ^, &, <<, >>).

code:
let mut x = 5;
x = x + 12;

let y: () = x;
Will tell you x is of type {integer} which is an infinite-precision int. The variable will remain this pseudo-type until x is coerced into a type implicitly by assigning it, calling a function, etc. All of these operations on these pseudo-types are done at compile time, hence why they're limited to built-in operators. You're not allowed to call functions like powi until the exact runtime sized type is known (f64). There's an argument that since you're assigning to an f64, the compiler's type inference should be able to work out you mean f64, but there's also an argument for explicitness that fits with Rust's general philosophy (such as requiring you to manually type convert from an f32 to an f64 if you're doing let result: f64 = my_f64 + (my_f32 as f64)).

It's on the roadmap for Rust to eventually allow compile time functions, const fn which signals a function contains an algorithm that may (but not must) be run at compile/startup time. These are usually basic math and initialization functions (such as building a new global Mutex), but there hasn't been agreement on exactly how it should work and what the restrictions should be. See the tracking issue here.

Until then, the lazy_static crate provides a macro that sorta does that. Instead of a const it declares a static wrapped in a function that's called automatically the first time the variable is read. This theoretically has some minor runtime overhead, but it works in most cases. There may be an argument against using a number declared in lazy_static in a hot loop, but I'd need to see benchmarks before saying that. The compiler may be able to optimize around call_once properly since I think it's a core intrinsic of FnOnce.
Where are you getting this idea that anything is infinite-precision? {integer} is an unknown integer type. It doesn't have magic unique semantics, and it doesn't get coerced because it isn't a specific type to begin with. Arithmetic operators on certain types work in const contexts because they're special-cased to be const fns, and are not special in any other way.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

Linear Zoetrope posted:

I think I got it confused with Go, which does do infinite precision arithmetic on literals.
So "1 + x" in Go can give different results for the same types depending on whether x is a literal or a variable? Whose idea was that?

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

Dylan16807 posted:

No, "integer constant" and "floating-point constant" are their own types.
So it's weak numeric types, where seemingly cosmetic syntatic changes lead to different semantics. Did we learn nothing from C?

Dylan16807 posted:

It actually makes things more consistent, because you know that (5 << 40) >> 40 is always 5.
Until any of those values gets refactored into a variable, at which point who knows!

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

Dylan16807 posted:

Is it really that much weirder than getting different results when x is uint8?
Is it weird that Boat::launch and Missiles::launch do different things? No, because they're different types, and their operations are distinct.

Sheep posted:

Anyone familiar with the openssl crate? I spent about four hours today trying to get a simple server going with very little luck. Complicating matters is the fact that all of the documentation I could find for the crate is entirely incorrect regarding SslAcceptor/etc. so I had to do a ton of source diving just to get things building (and then failing with no ciphers available).

Trying to keep dependencies light so not really interested in using tokio/native-tls/whatever else. I've got the client side written in Rust using openssl with no issues talking to a Python-based server so halfway there, in some sense.
If you found the documentation to be incorrect, you should report a bug; the crate is actively maintained. Though if you really want light dependencies, rustls might be better since you don't have to worry about foreign libraries.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

Dylan16807 posted:

Does that mean you're agreeing with me now?
The problem with go's approach is the weak typing, if that wasn't clear. If their compiletime-only bigint implementation was strongly typed, that would still be gratuitously weird, but comparatively harmless.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
Usually makes sense to have implementations next to their structs. Note that rust does not have anything called a "class," and does not seek to imitate OOP patterns for their own sake.

Traits must be imported for their methods to be used because any crate can define and implement a trait for any type, which would otherwise allow arbitrarily distant transitive dependencies to introduce ambiguities in completely unrelated parts of your code.

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
Or, more concisely, mem::replace(&mut self.map, HashMap::new()).

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
I maintain Quinn, a QUIC implementation with a futures-based high level interface (QUIC is a very cool upcoming network protocol being standardized by the IETF, it's kind of a best-of-both-worlds-and-then some thing when compared to TLS+TCP and UDP), and openxrs, a binding to the excellent provisional OpenXR API for virtual reality applications. I also have various low-level real-time graphics crates, and contribute to a bunch of other stuff like tokio and ash.

Progressive JPEG posted:

Is there a way to update the README content included on crates.io without cutting a whole new release? I added some README content in the repo but there hasn't been any need to change the code. The sole image link in the crate README has stopped rendering as well, because they apparently just link back to the repo master for images rather than importing them. "Immutable" my rear end.
Sadly you have to make a patch release for metadata updates. Fortunately this is easy and harmless.

Ralith fucked around with this message at 05:30 on Jul 14, 2019

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
My comaintainer set up dependabot for Quinn, which has been decently handy for keeping on top of updates.

Adbot
ADBOT LOVES YOU

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

Hadlock posted:

Trying to figure out how to create a nested struct that has an array at the top level struct. Stuggling. I am trying to do one of those 2D rendered spinning cube things, which involves three primary structs,

Position: xyz coordinates as f64
Wire: start and end positions

Cube: An array of 12 Wires

I can't figure out the struct declaration syntax to do this. I'm sure it's relatively straightforward and simple. As a test, I have tried creating a zero-ed out array of u8 and then would implement it with specific values after the fact, but, yeah. For this example I've sucked out most of the irrelevant bits. I've got a simple cube struct as a placeholder for now. Thoughts? ha;lp
I'm having a hard time following what you're asking here. Are you trying to make Cube.wires be an array of structs? Write the name of your struct type, "Wire", instead of u8.

Judging by your code, you may also need to remember that Rust doesn't have C++-style constructors.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply