By using this site, you agree to the Privacy Policy and Terms of Use.
Accept
World of SoftwareWorld of SoftwareWorld of Software
  • News
  • Software
  • Mobile
  • Computing
  • Gaming
  • Videos
  • More
    • Gadget
    • Web Stories
    • Trending
    • Press Release
Search
  • Privacy
  • Terms
  • Advertise
  • Contact
Copyright © All Rights Reserved. World of Software.
Reading: Rust: A Productive Language for Writing Database Applications
Share
Sign In
Notification Show More
Font ResizerAa
World of SoftwareWorld of Software
Font ResizerAa
  • Software
  • Mobile
  • Computing
  • Gadget
  • Gaming
  • Videos
Search
  • News
  • Software
  • Mobile
  • Computing
  • Gaming
  • Videos
  • More
    • Gadget
    • Web Stories
    • Trending
    • Press Release
Have an existing account? Sign In
Follow US
  • Privacy
  • Terms
  • Advertise
  • Contact
Copyright © All Rights Reserved. World of Software.
World of Software > News > Rust: A Productive Language for Writing Database Applications
News

Rust: A Productive Language for Writing Database Applications

News Room
Last updated: 2025/06/12 at 8:28 AM
News Room Published 12 June 2025
Share
SHARE

Transcript

Lerche: I’m Carl. I work on Tokio primarily, the open source async runtime. I probably started that about six, seven, eight years ago now. Now I’m doing that. I’m still working on that at Amazon. I’m at Amazon, but I’m working on Tokio there, so I’m on the open-source team. I’m going to try to convince you that Rust can be a productive language for building higher level applications, like those web apps that sit on top of databases, like the apps that back mobile apps or web apps.

Even if I don’t convince you, I’m going to try to have you leave with something of value, I’m going to give you some tips and tricks that will be generally useful working with Rust. How many people here have already written Rust? You’ve heard of Rust, I assume here. You’re not here for the Rust computer game. It’s ok. You don’t have to know Rust, but you know a little bit about it. Who already believes that Rust is generally useful for higher level use cases, that are not performance sensitive? Hands up, you’re like, “Yes, I will use Rust for building a web app now. It’s the best language for everything”.

Overview of Rust

Rust is a programming language that has roughly the same runtime performance as C or C++ do, but does this while maintaining memory safety. What’s novel about Rust is it’s got a borrow checker, which does that enforcement of memory safety at compile time, not at runtime. Rust is still relatively new, relative to other programming languages. At this point, it’s gotten to the point of being established. The rate of growth over the past few years have been really quite stunning. It’s gained adoption at quite a number of companies, small companies and big companies, Google, Amazon, Dropbox, Microsoft, they all use Rust these days. Amazon, where I’m at, we’re using Rust to deliver services like EC2, S3, CloudFront. You might have heard of them. Rust is being used more within these services to power them. It’s become an established language.

The vast majority of Rust’s adoption these days is at that infrastructure level. For networking stuff, I’m talking about databases, proxies, routers. It’s definitely less common today to see Rust being used for higher level applications like those web applications. I’m not saying no one does it. Some people definitely have, I’ve spoken with them. Mostly Rust is used at that infrastructure level. I’ve been using Rust for 10, 11 years now, which actually I thought about it, that’s the core of my life, kind of scary.

When I started using Rust, when I got involved with Rust, I also was like, ok, Rust is a systems level programming language. It’s used for those lower-level cases. I myself did not really think, Rust is a good use case for those web apps. That’s not something I considered. Over the past couple years, personally, my mind’s been changing on that. I started asking myself, is that really an inherent truth? Is Rust really only a systems language? I’m not a Rust maximalist by any means. I know I probably might sound like one, who’s like, use Rust for everything. I don’t actually believe that. I believe you should just use the best language for the job. When people ask me, what language should I use? Oftentimes I’ll say something else. We should pick the best tool for the job.

That said, what the best tool for the job is not necessarily a black and white answer. You really want to pick the language that’s going to be as productive for you for that use case, but productivity has many aspects. There’s the obvious one, how quickly can you ship your features? How quickly can developers on a team work together? How quickly can developers ramp up? It’s also the context of like, what do developers know coming in? Because you take a bunch of, it doesn’t matter, JavaScript developers, Java developers, and you put them on a Rust project solo, they’re not going to do very well. The reverse is also true. Throw me on a JavaScript project, I’m like, I don’t know. I probably wrote JavaScript a while ago. I forgot everything.

Then, besides just shipping features, there’s just actually getting the level of quality that’s required by the project. By that, I mean not all software projects have the same quality requirements. I’m sure we all believe we ship great software all the time. Realistically, sometimes you just got to ship. Bugs are ok. When you’re building a car, hopefully that’s not true. Different levels of quality depending on what you’re actually working on. Lots of aspects to consider.

How Rust Fits in Different Dimensions

Let’s talk about how Rust fits within those different dimensions. The first one being quality, that’s where Rust really shines. It’s an entire value proposition. Rust is a really good language for writing high-quality code with, both from a performance point of view, but also from the point of view of minimizing defects and bugs. On the performance side of things, that’s like what you hear about the most. Rust is really fast. It’s compiled. There’s no garbage collector. That’s not new. C and C++ do that. Those have been around for a while. Why haven’t those gained as much adoption as Java? Because there is that quality side of things. With C or C++, about 70% of all high-severity security issues are memory-related. If quality is an issue, maybe C and C++ aren’t the right choice, which is probably why there are languages like Java. Less obvious, you’ve probably heard of some stuff like fearless concurrency.

Rust’s type system can prevent a whole bunch of other bug categories, like data races. Rust’s really good for writing high-quality code. Maybe some less good things up until now if all things were equal, Rust would be a pretty slam dunk sell, high-level or infrastructure cases, but all things are not equal. Most of the complaints I hear about Rust when talking with developers can be summarized as, Rust is not as productive. Usually, that’s not what people tell me. There’ll be things like, when I tried to use Rust, I ended up fighting with the borrow checker. Or maybe you hear things like, Rust is great when it compiles, my code just works, but getting it to compile can be challenging. These are the kinds of things I hear. That really does boil down to that question of productivity.

Right now, the choice developers are making when picking Rust is to trade that development time, so longer development times for higher-quality code, but less development time than if you’re going to use a different language to reach that same level of quality. If you have a software project, that performance bar is high and that quality is high, you’re going to actually be able to reach that goal quicker with Rust than other languages. If maybe you’re willing to sacrifice a bit of quality for faster development time, maybe it doesn’t make sense. That’s the general sentiment you hear around online discussions with Rust for those higher-level use cases. The borrow checker, it’s all just unnecessary overhead.

Is that actually true? So far, maybe it doesn’t sound like I’m making a great pitch. Is the type system and the borrow checker fundamental overhead that comes with Rust? I do think there’s a kernel of truth, but reality is a bit more subtle. Again, in my Rust journey, I started with that same belief that Rust is not as productive as other languages, that it really is only good for systems-level programming. After talking with a whole bunch of teams that have been adopting Rust within their organization, that’s not really always what I heard. More often than not, the stories I heard started with like, a team had some performance requirement for some feature, and they decided to look at Rust for that project, so their team learned Rust. They were able to ship their code, meet that performance requirements, oftentimes, with minimal tuning.

Then they started noticing, over time, their software ran more reliably. They got paged less. They also noticed, as their team got more familiar with Rust, because they had to keep working on that software over the lifetime of that project, as a team, they didn’t actually notice their productivity drop as maybe they would have expected going into it. They still maintained that productivity. Also, they found lots of other different advantages as they started adopting Rust more in other cases, like in more higher-level cases themselves, that they were able to get more code reuse and other benefits like that. I started hearing the story over and again. I started to reevaluate my own assumption that Rust is not as productive.

Yes, it’s true, Rust is maybe not the best language for prototyping. First, that type system really does push you to write correct code. When you’re prototyping, you want to get your code running fast, even if it’s mostly broken, Rust’s type system might get in the way of that. What Rust lacks for prototyping, it makes up in the long run by speeding up development time over the long term, so over the entire lifespan of a software project. Code tends to live a lot longer than you might originally expect. How many times you just write something, it won’t last long, and then 5, 10 years later, it’s still there. That happens more often than we’d like to believe. The type system, yes, it can add friction when prototyping. Then the other side of the coin, it makes Rust more explicit. If you’re just looking at a piece of Rust code in isolation, you know a lot more about it than with other languages.

For example, if you get a mutable reference, you know that you can’t mutate that code elsewhere. That matters a lot because we’re going to be reading code a lot more than writing it over the lifetime of the project. Besides just references, in general, Rust tends to prevent a lot more of the hidden dependencies or magic. Just looking at Rust code, you can tell a lot more what’s going on, and that has benefits for that maintenance aspect. Things like during code reviews, debugging, all the stuff that you have to do to maintain a software project over its lifetime, Rust helps speed that up. It helps improve the productivity of the team over that lifespan. If you’re spending less time on that maintenance aspect, it also does mean you’re spending more time building new features. Anecdotally, this is what people tell me as they’ve used Rust over a couple years. That is where they’re seeing that tradeoff happen and part of why they are seeing their productivity with Rust stay just as high as with other languages.

Rust’s Learning Curve

You may have noticed up until now, I’ve been qualifying things with, once they have successfully adopted Rust. What I think is true today is, Rust is harder to learn than other programming languages. There are a number of reasons. While it’s true Rust as a language isn’t trivial, I think a bigger reason why Rust is harder to learn is that it’s a pretty different language. One, it looks like an object-oriented language if you squint a lot, but it’s not. It’s not at all an object-oriented language. One big pitfall I see when people are coming to Rust and learning Rust, especially coming from object-oriented languages, is they take their patterns and they try to apply it to Rust, and then that just goes poorly. What if we could make Rust easier to learn? I think that is going to be a big step towards making it a compelling language for that higher level because of how the learning is a big part of what is that initial productivity friction that teams see.

Second, and this applies more to Rust at that higher level, which is what we’re talking about now, is that the Rust ecosystem is a lot less developed than something like JavaScript. JavaScript ecosystem has tons of libraries, off-the-shelf components. Other languages do too. Rust, less so for the higher-level use case, and that’s in part because of Rust’s history coming up as a systems level language. Because if you’re building something at the systems level, the ecosystem is actually really developed there. There are libraries for a lot of different things and they’re all really nice. That’s part of that self-fulfilling cycle where Rust says it’s a great language for systems level programming. Developers come, they build stuff they need, more developers come, there’s like a self-reinforcing cycle that hasn’t really happened at that higher level. The second big aspect, I think, that we really need for Rust to really get to that level of being a great language for higher level is a more developed ecosystem there.

There’s not nothing. What libraries are there today for building those higher-level web apps, database-backed apps? At a very high level, to build a database application, you’ll need to have some HTTP router, takes inbound requests, and you, as the developer, handle those requests by using a database client, an ORM or something, and then you send the result back over the HTTP response. What is there as the ecosystem? There are libraries to do the router side, definitely a lot of good options there. There’s Axum, there’s Warp, there’s Actix, and probably others.

That website, arewewebyet.org, is definitely something you should go to if you want a more comprehensive list to find things. I’m personally partial to Axum, so if you go look at one, I recommend Axum. The state there is pretty strong. For the database client side of things, I think there are fewer options. Diesel, the original ORM for Rust. If you’ve tried to use Diesel, it works. I’ve heard that it can be harder to use. The main other options can be something like SQLx. It’s a nice little library if you like writing your SQL queries by hand, but personally, I think there’s really a need for those higher-level use cases to have a nice high level ORM.

Personally, over the past year, I’ve been working on that. Toasty, it’s open on GitHub, but be warned, it’s still in the very early days. It’s more of a preview, it’s not released on crates.io. The examples work. Lots of panics. Again, very early days. I’m hoping by sometime next year, hopefully mid, probably later, it’ll be ready for real-world apps, but I really want to get it out there and get people looking at and providing feedback early. Goals for Toasty. Toasty doesn’t just target SQL. Toasty does not abstract away the datastore, so you can’t use Toasty assuming SQL, then swap out the backend transparently to a datastore like DynamoDB or Cassandra. I don’t think that’s something a library can reasonably do.

However, personally, what’s bugged me when I’ve looked at ORM libraries in the past is there tends to be this full ecosystem split between ORMs and libraries that support other types of databases when there really is 90% overlap. The majority of the work that these libraries do is that mapping between structs and your database and doing create, read, update, the basics, so basic queries. Having to always have complete splits between those two ecosystems always bugged me. Toasty starts with the basic features that are common across all of these different flavors, and then lets you opt in to database-specific capabilities, whether that’s SQL or DynamoDB or Cassandra, but also prevents you from doing things that wouldn’t work on each target database. You obviously don’t want to do a three-way join on Cassandra.

Second and more importantly, I think, is that I really wanted to build a library that prioritized ease of use over maximizing performance. That isn’t to say that Toasty doesn’t care about performance, but you’re using Rust, you are coming here for things to be pretty fast. When designing the flow of Toasty, when designing the happy path specifically, I’m focusing on ease of use. If there’s a design tradeoff that I have to make between ease of use and really getting that last bit of performance, I’m going to pick ease of use here. That brings me, again, back to learnability. I do think Rust can become easier to learn. Yes, Rust has features that can be complicated and harder to use.

If you’ve looked at Rust, you’ve probably had these and you probably know what I’m talking about. I believe you don’t need to use these features to be productive with Rust. The basic Rust language is not that hard and you can be very productive with it. For Rust to really get to that point where it can really be a productive language for that higher level case, one, learning materials need to focus on that core, easy part of the language, and libraries need to focus as well, not bring in all the hard features.

Hard Parts: Traits and Lifetimes

What are the hard parts? When talking with developers who say Rust is hard, it really comes down to either traits or lifetimes, somehow. Both of these topics are not trivial. If you’re new to Rust and you structure your code wrong with these two features, it’s really easy to dig yourself into a hole that’s hard to get back out of. I think that part is really the biggest part of what contributes to that feeling that Rust is hard to use or not as productive. Because once you become more experienced with Rust, and that experience comes over a non-trivial amount of time, you know how to use these features, you know how to avoid the pitfalls, but that’s not really something helpful to tell a new developer that has to ship something next month.

It’s like, don’t worry, in like six months, you’ll be an expert at these things, or something like that. What do we do about it? If traits and lifetimes are hard, maybe the answer is as simple as avoid using them. Maybe it’s a little controversial, but I think that most developers using Rust can become very productive with hardly touching these. The problem is that, again, learning materials, will introduce these early, and a lot of libraries use traits and lifetimes heavily as part of their core APIs. You pick some of these beginning libraries and you’re like, ok, and there’s like five lifetimes stuck in this basic API that you’re supposed to call. I’m like, why?

Tips and Tricks for Using Rust

Personally, I started compiling a set of tips and tricks for using Rust. At Amazon, we got a lot of new developers onboarding Rust. I’ve had to compile some things that I tell them on their learning journey. They’re not just for beginners. I find myself following these as well when writing Rust. I’m not going to be giving you a tutorial of writing web apps with Rust. I don’t think that’s super useful. You can go and look at the guides, like Axum guides and Toasty if that’s what you want. Instead, I’m going to go over some of Rust features that I like and try to put those in context of building for web app developers. Hopefully, those tips and tricks, if you go and read the guides and learn Rust and maybe even talk to other developers who are within your org, teach them Rust, those will be helpful. The first tip is, really try to prefer using enums when possible. A trait is a way of defining generic code. You should use traits if you don’t know all the possible types that are going to be passed in. This is especially true for libraries.

You might want to write a generic function and you don’t know all the possible types ahead of time. That is true. You probably need to use a trait there. When building the application, like the end product, we do know all the types that are going to get passed in. We don’t need to use a trait. We can use an enum instead. This is going to greatly simplify our code. This principle applies in many cases. One time I see it come up often is that question of mocking.

This comes up a lot, how do I mock in Rust? It’s so hard. I get these questions a lot because, again, at Amazon, I’m on the Rust team and we get all of the questions like, how do we do this in Rust? I know this question comes up a lot when building these apps. Let’s look at a quick example. Imagine you’re building a very basic payment processing routine. You have your billing client that issues network calls, and you want to test this by mocking the billing client. This is almost always why I see people try the first time. They define a bill trait and then they go make their billing logic generic over that trait. The problem is going to be that you have this trait bound but this trait bound is going to leak everywhere in your application as well. Not just that, it’s going to start like that bill at a very high level but then propagate everywhere.

Then you have all of these different traits. If you keep adding more traits for every single thing you want to mock out, this is going to just compound and become super complicated. Again, this is an application that you control all the types that come in. You know there are only going to be two implementations, the real billing client and the mock one. The easier option is going to be just to use an enum here and list out all the billing clients as variants. You avoid using the traits. There’s no more trait bounds. It adds a little bit of boilerplates to define that enum, but there are crates out there that can help get rid of all that boilerplate and you’ll now have no more traits in your handle payment, and that won’t cascade everywhere.

A nice segue to procedural macros. Procedural macros let you write a Rust function that generates code for the user at compile time. That enables a lot. I do think it’s one of Rust’s superpowers that can unlock a lot of productivity and really actually is one of the reasons why Rust can be competitive for productivity at that higher level. Let’s look a bit about it. Here’s a Hello World example with the Axum library. That JSON exclamation point, call the contents of that, that’s clearly not Rust syntax. It’s JSON syntax. Rust has no support in the language for JSON syntax, but this compiles. The way it works is that there’s a Serde JSON library.

If you use Rust, you probably already heard Serde. It provides the implementation for that macro call. It’s implemented as a Rust function that takes a syntax tree and transforms that syntax tree to something else. In this case, an instantiation of a Rust value representing that JSON. I’m not going to labor too much. Again, you probably know Serde. Here’s a derive attribute macro and it works in a similar way. That struct definition is passed to Serde as an AST. Serde takes that and then generates transparently all the code needed to serialize that struct. Now you can use it as an Axum type response, and that’s really powerful.

Applying this at Toasty, the ORM library I’m working on, I think the initial obvious way to design the library would be to use a procedural macro on structs that define the database schema, something like this. I decided not to do this, at least initially. I’m going to tell you why. Procedural macros are one of Rust’s superpowers. As you start using Rust and you end up using it more, you’re probably going to start writing some. They do come at some amount of cognitive cost. You’ll even notice this, like there’s definitely an undercurrent of pushback to procedural macros within the Rust community. I don’t think it’s because procedural macros are bad. They’re definitely great, I love them. You need to be aware, again, of this cognitive cost. They generate all of that output transparently at compile time. If you need to debug the output or look at the output, that is, I think, where some of the problem comes. Just ask anyone who’s tried to debug proc_macro output. It can be challenging.

For Toasty, instead I took inspiration from Prisma, which is a JavaScript ORM client. They do a separate schema file, and code is generated from there. In a lot of ways that’s similar to procedural macros in that there’s a program that generates code for you. The difference being is it generates real files that you could open up and look and see all the output of the generated code. I think specifically for Toasty, that’s pretty useful because Toasty generates a lot of structs and methods that the developer is supposed to use. For example, this user find_by_email method is generated by Toasty. If you can just open a file and read it and find all of those methods and just explore it like real code, I think that’s useful. Does that mean this code generation strategy is superior to proc_macros? Not at all. They’re different. I think it depends on the context. The reason why I’m bringing it, again, if you get to this point where you’re starting to write some libraries and introduce proc_macros, I think this is going to be something to keep in mind.

How do you decide between these two strategies? For me, there’s two different factors that I consider. First is, how much context from the surrounding Rust code is required by the macro? If the answer is any, I think odds are that you’ll be better off with a procedural macro instead of that external code generation strategy. A quick example, again, revisiting that JSON exclamation point macro, you could see that the contents of that macro referenced variables, so that’s highly contextual. Just from the conceptual level, the response struct is very tied to that specific request handler. It would be a bit jarring to have to jump to a different file to see how each is defined. Highly contextual case, and I think this is a really good use case for procedural macros.

Then, the second factor is, how important is it for the user to discover the details of that generated code? Just how important is it to just read the generated code? I’m going to consider the Serde derive example again. The procedural macro here generates an implementation of that serialized trait. The trait definition itself is public. The specifics of the implementation don’t really matter as much, because it’s just an implementation. It’s a lot less important for the user to just open up that generated code and read that implementation. Again, I think this is a great use case for procedural macros. Toasty, on the other hand, it’s going to generate a lot of bespoke methods, which is why I decided, again, initially to go with a code generation strategy. In short, code generation is a great strategy to reduce boilerplate. Proc_macros is one of Rust’s superpowers and a super-helpful way to do that. Just be sensitive of how much code is generated and how the user is supposed to learn to use that proc_macro.

Back to traits. Yes, you should prefer enums over traits, but there will be times when a trait is appropriate, especially when building libraries, traits are a necessity, like I said. I still think, even for the library case, preferring enums over traits applies. When adopting a trait is necessary, just try to keep it as simple as possible. Doing something like this is probably ok. It lets the caller pass in any type that can be converted to a string. This helps avoid boilerplate. It can be good. This, on the other hand, is what I’m calling a second-order trait bound. The more complicated the trait bound, the harder it becomes for the user to reason about what types you can pass in. The compiler messages get harder. Now you can start to see, this is hard to reason about. This is why new people come to Rust, say, it’s so hard. It’s stuff like this. To have a trait bound like this, there has to be a ton of value to that trait bound so that that value outweighs the complexity. I think, historically, Rust libraries have leaned too much on traits.

In my years, I’ve definitely been a big offender of overusing traits. This example here comes from Tower. It’s a simplified version. It’s a library I worked on that uses traits heavily. There is an argument for it, but I think it’s not worth it, is the short of it. The theme of this talk is really, as you get familiar with Rust, you’re going to be lured into the power of Rust’s advanced features. Try to push back and really focus on how newcomers to your code, whether it’s a new developer from the organization coming in is going to be able to read this and understand it.

For Toasty, this is the generated find_by_email method I mentioned earlier. The argument is a trait. It’s a first-order bound. I’m hoping that this is the most complicated usage of traits that 95% or more of Toasty users will experience. I did include a lifetime. It’s one of the hard parts as well. There’s a similar theme to try to avoid using lifetimes and instead pass return values. Here, I’m including a lifetime. I’m not 100% sure it carries its weight yet, which is why I’m hoping you try Toasty, tell me what kind of experience you have. I may or may not end up getting rid of this lifetime here.

Result vs. Panic

Let’s talk a bit about result versus panic. Result is a type. It’s typically used as a return type to make it explicit to the caller of a function that that function could encounter an error. Languages like Java would handle this usually with an exception. The advantage of making error handling an explicit part of the return type is that it does force the caller to be aware of that error and handle that error, or their program will not compile. That is a big part of what leads to fewer bugs with Rust, because you can’t necessarily forget about handling the edge cases with exceptions. Rust also has panic, which is a different way of modeling errors. Panics are a lot like exceptions in that, if you panic, it stops the execution flow and starts unwinding the stack. A panic is going to be pretty harsh and really is for when something goes pretty wrong.

Two ways of handling errors. Which one do you choose? It really comes down to whether the caller is expected to handle the error case or not. Let’s say you have a socket. You’re reading data from the socket, and the socket unexpectedly closes. That is an error case that will happen in real life. You, as the programmer using the socket, you should gracefully handle that case somehow. Socket operations in Rust, all the methods are going to return result. Now, when to panic. This is going to be for error cases that have no sane way to handle at runtime. What I mean by that is, oftentimes, that’s a bug in the caller’s code that ends up in an unexpected error case. Handling bugs in your own code and responding to errors like that is a lot. To hard stop makes sense there, because if you have a bug in your code, you are now in unexpected state that is hard to recover from. A panic is going to be usually when there’s a bug in the code.

To illustrate what I mean by a bug in the code, let’s look a bit at Toasty. I want to talk a bit about how Toasty handles the n plus 1 problem, which is a textbook ORM problem. Here, when we’re loading a user, we’re iterating the todos, and we’re printing the todos category. The n plus 1 problem is if the ORM implicitly and lazily loads associations and issues queries when it’s loading those associations, there’s going to be a database query that’s issued for every iteration of that loop. That’s bad. What you actually want to do is load all the necessary data up front. In this code example, when you’re calling find_by_email, Toasty doesn’t know that you’re going to want the category. First, with async Rust, it’s not actually possible for Toasty to implicitly load that data on demand, because at every time there might be a network call, there needs to be a .await. That’s actually pretty nice, because now you can look at this code sample and immediately know where the database queries might happen.

Again, recall I mentioned hidden dependencies are magic earlier. This is another illustration of where Rust, the language, can prevent that. Here, the only database query that gets issued is to load that user up front. If only the user is loaded, what happens when you call user.todos right there? Toasty panics. I specifically didn’t want that todos method to return a result, because as a caller, what would you do in that case with that result? You’d have to add boilerplate every place to handle it, which probably the only way to really handle a result in that case would be a .unwrap. That’s going to add a whole bunch of unnecessary friction when using Toasty the library. To avoid that panic, the caller then specifies which associations they want to eagerly load at query time. If you try to access the association without eagerly loading it, that’s a runtime bug, so a panic.

Using Indices for Complex Relationships

One quick tip for the road. You may have heard it said that you can’t implement a doubly-linked list with Rust, as an example of the borrow checker limitations. You can. It’s not actually true. You can do it. You can implement that doubly-linked list with Rust without using any unsafe code, if you store the nodes in the vec and then use indices to represent links. That’s a pattern that’s super useful once you get to modeling more complex data. It can be scaled up, again, to more complex data relationships. If you want to watch another video, this video covers it in great depth, youtube.com/watch?v=aKLntZcp27M. I highly recommend it to everyone as a almost required viewing.

Summary

What’s my point with all this? I do think Rust could be a great general-purpose language, including for those higher-level use cases like database applications, where productivity is more important than performance. There’s still some work to get there. Primarily, we need a more fleshed out ecosystem for those higher-level libraries. I’m trying to do my part. Part of why I’m giving this talk is to convince you that Rust has that potential. If we can reach that potential of growing that ecosystem and making Rust easier to learn with libraries that are easier to learn, learning materials that focus on ease of use, we can get to the point where we have this language that is really fast, lets you write more reliable code, lets you get paged less often, and is as productive.

At the end of the day, building these web apps is almost just taking all these components and gluing them together. I don’t think you need to be an expert in lifetimes and traits and all that to do that kind of work. That is my main point. Try out Toasty. Give me feedback. I’m still myself trying to figure out what exactly is an API for that ease of use. Feedback is super useful.

Questions and Answers

Participant: Your argument of enums versus traits, you show an example where it’s pretty messy if you use traits. You have a very clean implementation, but the trick is the messed up function. When you argue for enums, you intentionally or unintentionally skip the implementation part, which I think is where the messy part will be. How do you then argue for enums if your code becomes forced everywhere?

My argument is, if you have enums, then you have to write code twice to handle enums.

Lerche: Yes, if you have enums, you have to write code twice to handle enums. There’s proc_macros to handle that for you. If you look at enum_dispatch, a proc_macro that lets you use that enum style pattern, just like you’d use a trait. If you have an enum, the only place you’re going to have duplication is in the implementation.

 

See more presentations with transcripts

 

Sign Up For Daily Newsletter

Be keep up! Get the latest breaking news delivered straight to your inbox.
By signing up, you agree to our Terms of Use and acknowledge the data practices in our Privacy Policy. You may unsubscribe at any time.
Share This Article
Facebook Twitter Email Print
Share
What do you think?
Love0
Sad0
Happy0
Sleepy0
Angry0
Dead0
Wink0
Previous Article The Cadillac Optiq Shines—but Its Upcharges Don’t
Next Article Non-Human Identities: How to Address the Expanding Security Risk
Leave a comment

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Stay Connected

248.1k Like
69.1k Follow
134k Pin
54.3k Follow

Latest News

Steam finally goes native on Apple Silicon, here’s how to try it – 9to5Mac
News
Amazon API Gateway Adds Dynamic Routing Based on Headers and Paths
News
Ransomware Gangs Exploit Unpatched SimpleHelp Flaws to Target Victims with Double Extortion
Computing
Garmin Venu X1 vs Apple Watch Ultra 2: Which should you go for?
Gadget

You Might also Like

News

Steam finally goes native on Apple Silicon, here’s how to try it – 9to5Mac

4 Min Read
News

Amazon API Gateway Adds Dynamic Routing Based on Headers and Paths

4 Min Read
News

How Long Can I Leave Fresh Chicken in the Fridge?

9 Min Read
News

Gousto founder: Rejection is part of the game – UKTN

1 Min Read
//

World of Software is your one-stop website for the latest tech news and updates, follow us now to get the news that matters to you.

Quick Link

  • Privacy Policy
  • Terms of use
  • Advertise
  • Contact

Topics

  • Computing
  • Software
  • Press Release
  • Trending

Sign Up for Our Newsletter

Subscribe to our newsletter to get our newest articles instantly!

World of SoftwareWorld of Software
Follow US
Copyright © All Rights Reserved. World of Software.
Welcome Back!

Sign in to your account

Lost your password?