We're sunsetting PodQuest on 2025-07-28. Thank you for your support!
Export Podcast Subscriptions
cover of episode SE Radio 644: Tim McNamara on Error Handling in Rust

SE Radio 644: Tim McNamara on Error Handling in Rust

2024/11/28
logo of podcast Software Engineering Radio - the podcast for professional software developers

Software Engineering Radio - the podcast for professional software developers

AI Deep Dive AI Chapters Transcript
People
G
Gavin Henry
T
Tim McNamara
Topics
Tim McNamara 详细解释了 Rust 错误处理的四个级别:1. 忽略错误,程序直接崩溃;2. 返回字符串作为错误,需要在调用端进行解释;3. 使用枚举定义多种错误类型,编译器强制处理所有情况;4. 使用第三方库简化错误处理流程。他还探讨了 Rust 错误处理与其他语言的差异,以及如何处理跨 FFI 边界的错误。他强调了 Rust 错误处理的最佳实践:循序渐进地学习,逐步扩展知识,而不是直接追求理想状态。 McNamara 指出,Rust 的错误处理方式与 C++ 等语言不同,它将尽可能多的错误处理工作推到编译阶段,以提高程序的运行速度和安全性。Rust 的类型系统非常严格,这使得在编译时就能发现许多错误,从而避免了运行时错误。 在讨论中,McNamara 还介绍了几种常用的 Rust 错误处理库,例如 `thiserror`、`anyhow` 和 `eyre`,并比较了它们各自的优缺点。`thiserror` 库用于定义枚举类型来表示不同的错误变体;`anyhow` 和 `eyre` 库更适合应用代码,它们简化了错误处理流程。 Gavin Henry 则主要负责引导话题,提出问题,并对 McNamara 的回答进行总结和确认。

Deep Dive

Chapters
The discussion begins with a fundamental question about what constitutes an error in Rust, exploring the concept and its implications in programming.
  • Errors are defined as unexpected inputs or unsatisfied preconditions that halt program execution.
  • Error handling involves splitting the program into main and exceptional paths.
  • Rust's strict type system helps prevent errors by pushing much of the work to compile time.

Shownotes Transcript

Translations:
中文

This is software engineering radio, the podcast for professional developers on the web at S E dash radio done map S C radio is brought to by the attribute I computer society I tripoli software magazine online, a computer datorg flash software.

Welcome to software engineer radio. I'm your host, Gavin Henry, and today my guest is to mara. Him is a well known rust educator.

He wrote the book rust in action and received a rust foundation fellowship twenty twenty three in recognition of his efforts. Moved language. He also runs excEllent touch death, a consultant's focused on the rush programing language.

Then hosts the youtube chanel broadcast as active on most social media platforms as tim clip. Then welcome back to software engineer radio. We last spoke twenty twenty one. Anything I missed in your bio like you d like to add?

No, no, thank you very much for .

the introduction. No promoter, okay. So the day the show is talking about rest area handling in rest, so I really enjoyed your talk for rust nation U.

K, which is about rest errors. So I thought i'd like to get you on the show again because that really helped me understand them. sir. Think it'll be great for our listeners to only explore arion software and bugs in general, but how rust helps us with them to avoid them and give us the flexibility to what we need to do.

Well, you look at a pleasure.

So I went to let the foundation before we move into what you called four levels of errors in rust, or that talk did for rust nation. U. K. So let's start. But every high, everyone, what is an error?

This is a deceptively difficult to question the answer. It's probably why you're starting with that because there are almost too well.

There are multiple different right, sir, if we think of let's just say that we have that we think of a simple program is starting going through some a series of instructions and then to mining in era, we could define IT as essentially at one of those steps, some input IT receives something that IT does not understand or does not speak. And so or there are some prety condition that isn't satisfied and then the program cannot continue to the next step. And then you can think of an era as a fork in the control floor.

And era handling is being a way to essentially split the program apart and down the heavy path. Let's say, all the main path is the control flier that you have intended. And down all of these era parts, which also could be used, we could use the term exceptional parts, which kind of hinted the name of exhibitions are smaller, less likely cases, which we have thought about beforehand as programmers of essence ely.

Ways of dealing with problems are that we expect that we might encounter. Or example, I talked about input, and I mean that in a very general scenes. But if you are a web framework, you expect that people will send you all sorts of nonsense from the network.

And so your web ramework should deal with input that does not satisfy, let's say, H T T P. Or and the definition essentially of what is valid input and what is valid input sort of slightly changes at each step. But the other side of what an error might b is something that is completely unexpected, or the program might encounter a state in which it's impossible to continue down ini path.

And the typical response, most programs at that stage will be to display h. The Operating system will just kind of close everything down, close all its files, shut down all of its network's sockets, fill the rain and essentially ask the user to restore the program. And the way that I think of you is, is to think of them as a lot of books in the road or Brown. What be in tinder or expect perfect.

Would something like a programme or rest in particular, assuming less an input is a certain thing that could also be covered by what you are saying, where the inputs are wrong. As an in dynamically type language, you you're assuming at something, but it's not right.

We have more inputs than just the data itself so that every block or every statement or every expression essentially has some extra material like the data type that IT expects. And if you pass a string into a function which is really trying to do perform mathematical Operations, you'll likely to have a very bad time.

Perhaps not if you, although there are some languages which have essentially said that our approach is to just except that and do IT the beast that we can, irrespective of the input, is a my understanding of pill, for example, is that if you pass in a string to a function that exists something new, merc and IT uses sk literal, especially you have numerals in the string or at the start of the string, then the pill will just exceed that as a number itself. And so there are huge philosophes, essentially, of software. And what is acceptable? A permissive in a large spectrum.

And that would dynamic is really important because rust is a very static programing language. It's a very fussy about data types. It's easy to laugh at pill and they have I can't believe that you treat to string as a number.

But rust, on the other hand, is almost the opposite, is embarrassingly fussy. IT distinguish between the specific bit wiz of different indigent types. And so the difference between a thirty tupid into gear is just as different as, let's say, a string and an ant and and say, a python on or anything else.

In fact, it's worse than that. In rust, you could have a data type which is defined as being sixty four bits wide. So IT has exactly the same representation is the native bit wit of the CPU was.

So most programs we are running on sixty four, the CPU is the data type which refused to an intimate that is exactly sixty four bits wide on every super architecture, and is a dead type, which this is assumed, the size that the C, P, U. Architecture is the same. Assume the C.

P, the IT with of the native wit of the CPU that you are being compiled for. Sorry, that's a very long couple of there's to say that you could have two values that both have that say the number forty two encoded as an unsigned into gear with sixty four bites and this point, to wit, a type which we call A U size. Every single bit is identical, all of the with the identical.

And yet the rust piled warf used to allow them to CoOperate. You couldn't add one with another. There is no implicit integer pasting or into promotion in the rust language. And so rusted is very, very strict. And IT makes things like every hand lying bury frustrating for beginners because it's so identic.

And why does rust handle area the way that does?

Because essentially the language itself with the language ecosystem has said that if we push as much work to me, the compiler, if we can avoid problems, then we should. And if you you have some cases where you, for example, I might compile my program on a thirty two bit CPU. And so is now the bit representation of my sixty orbit type and my thirty two bit type are different.

And so this might imply some different semantics. And so now the inputs to the program actually include the CPU and the Operating system that the program is being compiled for. And rust is attempting to reduce the possibility of era by passing as much as I can at compile time. Once we remove the possibility of areas formal program, and that unfortunately involves being fussy sometimes, then we have programs which run exceptionally fast, as fast as they could by writing native assembly, or even I see code without the possibility that I could explode a new face. So because we don't need era chicken in so many places, because there are guarantees which are provided by the language itself, and I checked beforehand before it's even run.

So I presume the rust creator did IT that way, because they love, had experience with keep up, lost another languages where at the first past you'll have writing your programme to do what you're trying to do. Then on the second past, you might be thinking about all hold if is a different architects, we need to what you just explain, you know, an answer that might be different. So we need to do some checks for that.

We need to do some checks for lisson. Did the rush creators push that all to compile time? Because they just be caught out at so many times? You have an insight as to the history there.

So I know a little bit about the history, but I probably second, third hand, but lets go the rust programming language was a sort of essentially an experiment when it's very early stage, bob, before one point or was an experiment on running programs currently safely. And there was an active model.

So IT look much more like an early or go then what emerged after the project was adopted by mozilla for the experimental replacement for the firefox way browser. IT became infected as as a terrible wood, but all of a sudden a large number of c plus plus developers swept in on the project and sort of see IT. Look, if you really care about the thing that needs to go super quick and we need to prevent a whole bunch of bugs that sleep us, us does not.

And one of the bikes that c plus plus allows because of A C heritage, are settled problems related to what is technically called into your promotion or essentially implicit type casting. And if you allow that in the language, then you will encounter situations at runtime when the assumptions that you have is the programmer and the assumptions that the runtime has are going to differ, and you encounter bugs. The rust designers at that point made a decision after essentially using the the language to build this new browse engine, that we should be quite strict on people because the language itself will find a home in the ecosystem of programing languages as being as fast as native code, but completely memory safe. And part of being memory safe, or part of the kind of the philosophy of the language of providing speed and safety, is that we should provide a bury a low overhead mechanism to handle areas. So in some sense, the rest way or the the rest approach is in opposition to the c plus plus model by a large number of programme is who is seem became exhausted with trying to find encouraged y bugs, trying to find bugs with exceptions just popping out of nowhere or any other kind of work, some things that they hadn't countered a long way.

okay. So thanks for that, him. So now that we have rushed in the community for some years, quite few years, at least ten, when people have experienced with the rush approach, would the creatures say IT worked out or if have been changed the way things did since they start at a yeah.

I think that there has been a general trend in the industry towards, I would take a functional style. The other thing which I haven't mentioned is that rest in corporate, why do a few contempts from functional programing languages? And what we will see shortly is that rust users a very functional style from actually and the M, L.

Family of languages that include high scale and or camel. Or dealing with its era types or the era process itself. And I generally think that a lot of ideas from functional programing languages have been adopted or incorporated into more traditional programing languages, let's says, a java or a sea shop or c POS. Plus these languages, which have typically been associated with either imperative or object oriented styles, used heavily in vote on court enterprise software.

Yeah, I spent a lot of time in the last year where the legs are. And then as I started getting rust more this year, IT felt rate someone for the last stuff. I quite like that when you if you talking about functional side of things.

yeah, lex a is a fun programme that would I have quite a few, i'd say, months verging on to years of mothballed earning and alexa experience.

That's a good lead into my next question to as a polyglot multi language programmer, which we both are, I would say we have opinions about dealing areas and those languages. Are you not rust you good or bad? If we were to step back and push aside that we love us, how would we classify the developer experience for handling areas in us not knowing we know, not knowing the wise that we already know?

Yeah, I think that the development experience hurt in two places. It's uncomfortable when you start. It's different. And IT is slightly unclear how to struct your programs because you don't get the same thing as exception.

You kind of in this unfamiliar rita, where it's difficult to think about the way that your program is structured and the way that you want to implement something that would be easy in python, let's say, or easy in whatever a praga pt language you come into us and suddenly you can do that. And specifically, i'm talking about handling exhibition. The other thing that's quite chAllenging is once you have written quite a lot of rust and you're starting to write your own libraries, you need to start to learn how to compose different erotic pes.

Now this sounds as slightly absurd to people that are unfamiliar with what i'm talking about. But buried probably fifteen, twenty minutes of what we're going to be chatting about with this into the fourth level of era. Handling essentially is a large number of good party creates or sort of open source libraries have painted red.

The ecosystem of rust programmer to proverb is more it's more than just gentle sandpapering. It's essentially rethinking how areas work. And so there's been civil teams actually to create an economic layer of era handling over the top. And the things that we started talking about, a forehand about rust being very pedantic and actually become exacerbated when you have upstream errors that come from different ways. Just very generally, there is a different category.

We might use the word of class except us doesn't have classes, but it's cold at a class of areas that are generated from I R input output, such as the file that we try to read from, we don't have permissions to read from or the file may not exist. That's a different kind of class of era source from a different module then an era that is related to using numbers in strength or formatting output, essentially converting data to strings. And so once you start trying to net all of these different errors together, it's an a place where rust feels very colum sy. It's very.

My next question, are there any best practices for handling?

I think the base practice is to work incrementally and and have expand your knowledge and rather jumping to an ideal state to stick within your mental model and then expand IT as you learn more about the language. For example, rusts trade system, and trade is sort of like an interface or an abstract by class. We might say something is an era which we could say IT implements.

The era trait is actually suddenly different than what you might expect. And so if you try to go directly to an idealized this practice without developing a mental model, you probably end up becoming lost and frustrated. And so that that is a yeah hope fully. That doesn't me just kicking the Christian away. Another way down to wish much more quickly is to say that the four levels that we're touching upon a progression and that eventually you end up at the fault level.

Yeah, that's how I understand fect. It's so briefly to what are the four levels in relation to the best practice that was just poking out.

yeah. I mean, if we were to think about this is kind of progressing towards some ideal state, I said, is the nice way to do IT. We could start essentially by ignoring errors and just crashing the program that way.

Then we move on to using a intially untapped information and things like providing a very, very basic something that feels like try catch with a very patrol era. And then we can add some special facility. And the the rust way that we do this is by creating, typically creating an um in num and rustle a little bit special.

They are richer than named constants in in the last level is to essentially, I said last over some of the some of the rough services that the the language exposes the problem with using an inm. This level three is that we need to implement every trade or every interface or every combination of era that we might encounter. We also need to teach rust how to print the thing to the screen. And that's quite clumsy. And so the the latter level is essential in an extension of the did with simple fied gone.

Yeah, I think I made a mistake arsan and gone straight for I should be using this library and not for understanding what i'm doing that the thing I know is what's create to use if you're doing a library in which right to use if you're doing a binary for users will get to that. So let's start with ignoring result of tea, a result type like the result.

Yeah, it's tRicky, right? So in source code, you've got capital result and then angle brackets, capital tea lose brackets. And that t represents the type that the result contains when some Operation is successful.

But it's annoying because frustrating because the initial tea feels like I should be typed. But actually it's I mean, IT is a tight but but IT isn't reckless. Clear what that actually mean.

Their apology that is not new as the language, or at least it's the convention. They blame the stranger library. Is that so what .

do you mean by ignoring this? And what would IT if you're using IT? What would that look like in what you ignoring here?

A result is kind of a meta type where it's it's a type that is has two sides. One is an OK side, which contains a tea that we're been talking about or IT has an area side. We can think of a results which is just a rapidly pe.

IT essentially is a container or something, and we hope it's the tea, but IT might be the e and so we call a method on our result object and amusing the term object. Best maine value, we call on red, and this is usually opens the result up black out. Well, we hope is the tea.

And we need to remember that rusts type system is extremely. And so we say we expect that the value inside the result will be tea. And then I can assign my capital t some value of type a to a variable.

And if i'm wrong in the assumption, then I brush that is one way to do IT. Another is that there are some methods which take in A A reference to something else. Let me have an example.

Let's writing to a file, then go to the around. We going to read from a file by, start by initialized a buffer. And I have a buffer variable and a file variable. When I call read on file, I pass in a reference to the buffer, and then the method will return a result.

If the result is okay, it's likely to tell me the number of bites that was actually able to be read, and on the other side will have some specific error message about the category of era there. For example, if I didn't have read permissions on the file, actually the buffer will remain empty. And one way to handle the era is just a essentially just go ahead and and hope that your buffer has been filled up and just essentially silence the program by assigning the result that is returned from the red to a variable which is never ready again.

In rust areas, our values, they do not interfere the risk of the program. They are not like exceptions that will interrupt and break the flow. And so one way to deal with ears is, yes, assigning to variables which are never used again, and we can be very explicit with the rest compiler, which will be very keen to give us a warning to say that it's an unused variable by perfecting the variable name with an underscored say that we essentially disgusting this value.

Okay, somebody is that if I understood that correctly. So the result is something that a function that either we write or we use from standard library or another library is returned. So it's not the result of the function. The result is a thing, like he said, think of IT like an object inside that you could have happy path that okay, or the other path, which is an era and are so we are expected to act on that result because that's why is in the way that is. But if we choose for a simple way to handle errors, we just ignore IT by assigning IT to variable that we don't use a perfect that with an underscore to the pillar shot up.

That's right. yeah. The difference between those two approaches, and the one was to call on rat on result, and the other was to use a variable which we never read from again, is that if you call on rap and IT, you're wrong.

And there really wasn't era. Your programme will crash though they are, they are suddenly different approaches. Where is if you assign a result object, which is an era? To a variable which is never used, then your program will proceed as if there was nothing wrong at all.

And we would potentially reach for this technique if we are just brought type in some plan our and quickly for ourselves. You know we don't want IT to be .

bomb proof precisely. The we would use an approach like that if there was a good two ways to think about IT. One, you're just riding something about twelve lions long.

And the other would be that there genuinely is a situation. Well, you don't care if an era are good because the result either side is fine. They say essentially it's I don't know when that would be the case, but presumably, I mean, it's available to you, but I don't in practice, I would. This is essentially just as getting started with the idea that a result could be either this happy path or this exceptional case. The eras site for site .

looking for that level one, a level two would be what we are calling, what you ve called returning strings as errors. What does that look like?

okay. So when we start to let's decide to define a result and we are not exactly sure what the all or people that will be excepting a result as the return value of would would want, we're still designing our A P I. One thing that we can do is to just push a string.

And then if a, if we want to essentially quite and quite raise an exception, all we need to do is put any text we want that's appropriate for the moment inside the a variant of results. Then what our calls will need to do is interpret the text on the calling side. So for example, let's let's talk about that case of reading from a file.

You could imagine a case in which the the read method on a file returns in era, or advertise a result which contains an era that is just a string. And then your Christ is what was wrong. And so you go and look in the string and say, well, and we do as string Operations.

Does that start with permission denied? Well, okay, if IT contains that the substrate, then we assume that the era from the Operating system was permission. There was some possible mission era.

in fact. So if we're looking into the string as an error, we will be returning the type of our to your user. So probably like a command mind thing or something, we would be writing.

oh, so user. And that scene is suddenly different. This is the application code that is importing your library. The user is not the end user, but some other program probably dum have a code which is probably called that you've return.

So if you are defining a result type, which is quite easy to do, then IT works in conjunction with methods on types that someone later on is going to be calling. And so the result that you are defining now, we will be interpreted by some other code that you probably don't have control over. Specially you're writing an open source code or you're releasing the library to the world.

Given your example there were you interpreting the string for the error? Understand you'd be at a point where you're trying to look for something else, say, right? Yeah, I understand russian denied, but you watch the art for a number I could look up or understand, you know, you've got different levels for, you know, our memory, or can write the problem system. No, wrong. Use a group that type .

stuff right. And we can actually. So another, instead of retraining, a string is the same concept.

We could return an integers. In fact, we could actually return because we've talking about file I O. We could return the lib sy erds themselves from Better defined by the Operating system. Now the interesting thing there with you, what you just said, is that you kind of need to look up the dogs to figure out what the specific number means. Essentially, the code is not self documenting.

Or it's another way of looking at that is that it's open to a different glass of errors if you made a mistake, if you passed an error message as a string or as an integra, but kind of misread something, we had a type and suddenly you've made a decision based on the most interpretation of the code that is being provided upstream. You open the door for another era, which is the era of handling your one. Now that's a motivating factor into kind of the next step.

Is that clear? Yeah I mean, so we were level to returning strings as areas. So we've gone past the step of just ignoring things. We feel a bit braver, bit clever. We so 啊 yeah, let's put some meaning into the error. And then we've had the next level where, or actually we need to cops like some other type of information environment, then leans us to level three, which is enough. I think that right?

yes. And the reason why in ums work in rust is because in ums have two properties. One is that they are these named constantly that you have kind of known from every language.

We are essentially, instead of having a role numeric, we could give you a name and we could group all of those herodes into some category or, you know, that's not use the word, but maybe a class. Now though, that's kind of one type of to open up. And rust provides a lot of extra richness to this by actually allowing you to pack data into each of these varium.

And so if you have ever used, see, see, here's the idea of an a tagged union, whereby one bite is used as a numeric tag. And then there's a sort of a struct door you can push whatever you want in into the remaining data that could be essentially a type bet. Is ini type inside the same of packet? Now in rust, you also have one extra very nice property, of instance, because the compiler knows that bear out that's a nine different era types in now in now that we're defining and you only handle six in your code, IT will refuse to compile l until you have added handling for the other three.

And allama to say that, again, rust will require that you handle all possible cases and will enforce this at compile time. And so your programs that use the C N I O erotic pe, they will require that you have thought about essentially every class of areas that could occur. And this is in something much more powerful than than just passing around and in a job because the compiler doesn't give you a lot of support, like the c compiler doesn't really care. If you have bet with the intaglio, where is in rust, we can actually ensure that you have handled the specific aivan in the way since IT wasn't tinted because you have no need to pass any strings, the compiler, and guarantee that you have at least thought about the cases that you're likely to encounter. You can have a catch al pattern match, which essentially is I don't care, but you've opted into that behavior, which is essentially a stronger thought than the compile, saying I expect that you don't .

mind if we just go back to return in strings errors. When we return something from a function, we have to act on that or sign IT to viable, ignore IT. So if we're trying to pull apart, but like you've mentions, return a resultant and then you pat much on IT to act on and check.

But things are, as you expected, we can get a massive for china match on strings. So I I would understand that. But with e num, we can divine what we want in a enum to mean what we want. Then russia complain that when the ena is returned on the function we've called.

yeah exactly correct. That lets say that we, you know, keep talking about the same era tight, also the same scenario. But again, we have we're reading from a file.

We might have permission denied, we might run out of memory. That is a lot of different things that could go wrong. The file could have been been deleted. We don't want to have to interpret anything where the Operating system itself can kind of do like it's giving us the information.

And what the compiler does with the type system is require that you are lifted out of the problem of dating to interpret what IT is that the Operating system hasn't ended. It's completely unambiguous and and is out of is this very liberating feeling where instead of matching on strings or kind of, you know doesn't start with this, or you know we often cold and with a type sculpt of jobs, copt of python or anything else. I sometimes I like any reasonable program like you're just compare against strengthen, is IT equal to permission denied or what have you and rust can provide something that is significantly more?

yes. So I was thinking in my head going back to see example Normally do a much on if it's ever code one or two or nine or if it's not even one, it's OK. If it's audit is this if it's negative is but you have to think about all line caps roll out.

Where's that forstall you with rest if you don't just do in on rap. I love at one, ignore the result if you are doing a match or not. Because you want to be robust, you pull apart the inner and act on every level of IT.

Or decide, he said, opted to ignore three of the nine possibilities. leave. great. right? Yeah.

that's right. There is another thing that you've slogged in there, which I quicking to to chat about, which is that in mini languages, and I was a good develop for a Better year. And hf, one stage, and people used to return negative numbers to indicate that there was an era.

And the other thing that they might do, especially and go, is used the zero value that indicate that there is a missing that essentially an uninitiated, zed valley there, for example, the empty string. It's essentially the same thing, saying no string at all. And last way to do that is essentially to wrap the inter ga that you are dealing with in another type and push a lot of work to the compiler and into the type system.

Because if you forget to check the negative numbers, main errors, then you have a real problem later on in your program, because the thing is numerically valid and your problems will only emerge when something some crash will occur because something occurred. 对我 was not expecting a negative number。 And now you have to trace back where we are on earth.

Did this negative number appear that all will buy the way he was, actually something I should have double with the era when I was first, when I was first created. And rust is not permissive in that way. And I think this is a huge benefit to robust and soft.

When do you reach for the inner method level? Three verses string?

Yeah so the I think if your a profession rust programmer very quickly, if you are just learning or if you are if you're still designing a library, you want to give yourself enough lix ibt to be able to change things quite quickly. And so you spending more time generating areas than handling. And so the string method was a loosely typed, a stringy typed. The kind of era type is is fine, but I would generally recommend that most programs that expect to live more than who hours should have a custom year type defined for him like.

okay, so i'm gonna move us on to the fourth level. I think we've covered what I need them is well on other help because they forces to deal with things which can get in the way. But that's that's a good thing when I get that level. Is anything else you want to cover off an alums because they are pretty core to everything before we move on to the library section.

yeah maybe a motivation of why you would go further. And so one of the things that you could do with this is use the upstream era as one of the variation in your own ero types. And so essentially, you're creating a super era that combines or essentially allows you to compose other, other types together.

And this is two problems. One is actually a lot of work to define its kind of composing in the source code. And then you have a lot of Billy mechanical work to be able to describe, essentially provide a representation of an area type in as a string.

And one of the things that we haven't talked about is that the era, trade and rust, that is, the error interface, is by merely concerned with the ability to serial ze the data type itself, that is, all errors should be able to be printed to a log file, and which is one of the reasons why string is able to be used as an artist. And in the case of an imam, a new type that you define a custom, the user defined data type has nothing implemented at all. You start by when you grow a type simply, when you, when you define IT, you also need to define every single interface that IT implements for every single track that the the type actually on works with. That includes how to print the thing to the screen and the serialized IT as a stream. right?

Thank you. So you're now elite ite. You know what you're doing with all the errors you you've hit level and and then you realize all I don't need student anymore, I can just reach for one of these libraries or I can completely rethink I do because somebody else to create this life yes.

that's exactly right. So you've just gone to listens to nearly hour of of me. I hope you do this every week. And now i'm going to tell you that, by the way, most of the work has actually been dealt with.

And the process of defining your own era types is White simple these days, with the help of of of macros, really, which do the job of telling the compiler what to do and so that you don't need to write in fuse code. And I hate being one of these people that does the same thing, which I remember really disliking, which is essentially teaching all of the fundamentals before teaching this advanced cheat. However, I feel like in the case of doing as fundamental as area handling, IT really does help to understand what these libraries are doing.

Otherwise you must handle them. Or othe wise IT becomes magical. And I am strongly opposed to magic and software.

Yeah, it's the same as any computer, but you need a little the man before you can not easily attraction. I think I agree. So are in your talk.

Got three, nine months. First one is called this error, windows spaces. That one is anyhow one word in that air. Third one, we're going close to our the end of the show. So if we could spend a couple of minutes on each three and where you would use them, I don't move us into rap up.

Yeah no, no, please. That absolutely fine. This era is a library or defining an um which represents different variance. And so for example, you'll say that IT has little helpful macros for saying this is how I want. This is the string that I want to print out if this variant is encountered or I am rapping an upstream era. And so the thing that I want the compiler to do is to dispatch to the upstream era, for example.

And would you be able to change the austral area to something that means.

yeah, yeah, yeah, you can assist to provide you with a couple of hooks to be able to simplify things or to make them more specific. For example, actually, if you look at the the documentation, the in the front page is an example, which is a data store area. So we are writing a library that is a client library for some sort of database.

And one of the types of errors that are am has is a declining. But the data store, the underlying network locket has shut down the library that we're riding. We don't know why that shut down.

And so we actually essentially inherent from the standard libraries own erotic pe. And here didn't, though, is a very model word in that case, but essentially we wrap the standard library's own I O era, and then we provide our own context, which is data store disconnected. And then essentially IT IT been prints out the the the secondary, or sorry, the in the era.

Yeah, I was think kind of something like where you are using A A third party chase on A P I or something and 能 赢 就 but when returns to five hundred, it's actually OK or something you can trample.

L L. hara. Yeah no, no, absolutely. That would be a perfect thing that you could do. You given the opportunity to go and inspect whatever has been saved as like all likely it's a five hundred, but they say five hundreds in the sense are actually acceptable because they have the ibi does not respect the standard of five hundred ds actually are signals that that there was an empty data state, for example.

and I understand this, are to be used. what? Well, for you to use IT if you're speaking to users of your programme with the error messages for mankind. User.

yes, this is kind of strange debate about which library should be used for application code visus libraries, which is a distinction which I actually don't think is particularly helpful. But actually the the last two libraries that I we're going to talk about now would probably in most instances, be more appropriate or got application card. This era right is a way to define your own results by which provides a lot of service.

But IT has the downside that your hard does IT involves us a kind of bureaucratic approach where all every single instance needs to be handled. And in application code, sometimes you don't care exactly why there was a problem. You just want to know that there was a problem. And maybe, Anita, the output with some sort of context or it's like what I was trying to do this, and that's the log line that is printed out. And for those kinds of use cases, the letter to library going to be talking about are probably bit a suit.

okay. And the next one will be anyhow.

right? So I would like to actually chat about anyhow in ear as an gain. Eir, the E Y R E A belling is a easily being two safety, different versions of the same idea.

And you should use whatever believer of that idea you prefer. But they are conceptual, identical. They just different takes on the same idea.

So tim, could you just read, define that for me? He's just said that anyhow, in air reliance on subtly different mechanisms for in representation.

What is that? okay. So so what what I mean there and I apologize that for for my voice is just kind of feeling a little bit sick.

But the difference is that those first to rely on something, none is a trade object. A, which essentially means a at something which can A, A, A trade object in rust can implement a, an interface, a IT. In our case, IT implements the the era interface, or in return, ology implements the era trait.

An era trait simply means that the thing can be represented as a string and can be even printed out to the console or logged to a file. The but if you receive a trait object, so you might have the, the era might have been generated somewhere in the call stack. IT arrives at your function and you're trying to handle IT.

The only thing that you can do is essentially going to read the message. You only are the actual concrete type that generated. The era has been erased and you're only left with access to the interface.

Wheres, this era relies on the an a concrete type itself, some new type you created which can wrap anything else that you've god. And this new type is if is represented as something which you can go and and speak quite thoroughly. Ly, uh, if you have ever used A C program, you might have encounter the term of tag union nearby.

You have some numeric tag, and then there is a data field, or sort of a struct field right next to each other. And that is how indus work inside rust. And you have access to go in chick, which tag the the era is specifically. So this era provides a significantly richer uh, experience, so you have much more control. However, the downside, sometimes you don't actually want control.

You would like to be able to exit the program as quickly as possible or to just know that something went wrong and it's now time to abort the program and returned a message to the user and in which case you might have more success just with there that say, this era are with air as an giant air or anyhow, which is simply is, is a way to be able to take whatever era was generated, because areas are values and routine that very quickly back up, exit. We can Anita to the string with some extra information. So often these other libraries have a methods to be able what annotator add context appealed to the message.

okay. I've got a question about I did a lot work on using rust from sea, and i've just hit this point where i'm looking to pass some more information back for brush top onto the seaside the seaside and and i'm not sure, if any, these techniques es are applicable, and i'll just explain what i've done. So we ve got an example of which we could you reach for, if any.

So i've i've got this project is as low as you can go and see IT listens on a socket for T, C, P, U, D, P, pretends to be a telephony system, and then logs bad actors trying to get into IT meter to make a voice. People call now for a long time. I wait to add tls support.

sit. T, L, S, modern feature, totally scared to do and see what to do and rest. So my journey so far has been pretty crazy. One in rush this year, learning how to add things like extern cy no manor, how things compile calling, rust functions through the use of a header that I generate, initially mining ly calling and using that from sea, then I have switched to buying again to generate IT. Then I get to build the arrest, 就是 wait, automate things with us, as you know. And then because this lesson T L S function actually logs things, I need to then go back on the right side to call existing c code, to log things, to ask, well, right, you know, a file accepted rather than rewrite the same code. So it's like a double foreign function interface.

right? So you're inside the yeah right. I into coming back and asking for more information yeah yeah.

So i've got to sorry, i've got to generate c style strings on the rust side. I put IT on the heap, then i've got to free them on the right side. And then I need to deal with error. error.

I do not in view you. This sounds like, yeah, I can imagine why you're asking for help.

So that was one of the drivers for the show because you know, the initial thing is to stick a box dynamic standard era on main and that is no good when you call the function from sea.

sadly. no.

So what i've done on the rush side and maybe some of these craters can can help me, as i've just made any functions I call seaside return authority bit instruction, and i'm just doing lipsey x success and exit failure and then printing an era to stand out there on the rust side. But what i've just reached for on the rush side is just on rapping things.

You let IT abroad because it's an important thing like IT couldn't find a tea and a private key. But then on your some of the stuff we chat about today, we've got the question or CoOperate or that passes the the error message up the chain bit um which I can't really use. So just looking for any advice given on what we said. Do any these pass the.

Not really. So what you're really asking is can we use the rich sort of these nice features that rust provides and sort of passed that across the if if I boundary and I centrally apply that and see, we can't do that in a way that makes the c code aware of what rust is doing. So i'll just possibly explain things to your listeners.

For example, a couple of the terms there were extensive and Normal. So the idea here is that a an external sea is an annotation on the rust code, which tells the rest compiler to use seize calling conventions. So we are essentially writing sea code, sorry, no. We are writing a function that obeys rusts sorry seas roles in rust, for example, see defined exactly the order in which local variables appear and how that has into registered and these sorts of things bit packing and a bunch of other stuff that most program is really don't want to care about.

The no mango says that um you that tells the compiler not to alter the names of the symbols away from the name that habit, the names that have been defined in the source code such that you can go and access the same symbol names from the sea side so what we're actually saying is, yeah so you know what is really difficult interaction your. You create me if i'm wrong, but you are establishing a conflict. So you're writing some software and rust that interfaces with a sea library that does your voice over IP. And then you want to be able to essentially use the the but you want to pass in that, say, the tea is connection that was generated on rust into the sea library. Is that how it's working?

Well, the sea is a binary. Okay, IT calls a rush function called listen T, L, S, which is a tokyo. Um thanks.

So just sponge awesome threads. So um and I passed in a configuration pointer into that function. So on the rough side um I understands whether I were in debug mode. We need to print error messages where the certificates live exception. I'm so just looking to understand if there is any sw more richness that can go between rustan sea .

because probably not at the raw level, but I think, sorry, not you, is the possibility of creating an abstraction layer between the two sides, between a lot of as glue or something. And this I this is just a case of a literally hearing your problem for the so this is an an idea.

You define a tract which is kind of a kid might be like deep, like era report or something, and IT could be either on the sea side or on the rust side, which he was more convenient. That has space for a you need to give IT like I see on on on the on the rest side. Last standard library has A C string type and you'll need to be able so you need to at a point that and then you'll need a links field.

And you should probably. In this abstraction lab, sort of as a link between, is that before returning the function on rust side, you going, chick, is this global variable? None, no.

This is kind of help, is a very seek invention that we define some kind of hidden symbol, A A global that we're passing around and your rust code very quickly. Chicks is something to find there. And if IT is, we then return an actual era that we can interpret based on some information.

And IT might be that you seem through a an actual string or might be eric codes or might be something else, but you want to put something in the middle. Ah in this action is a relatively common. So in your if you exposure, you have to a fear number of create.

In the rest ecosystem, you'll see that they define Normally to create to intervac for one sea library. There will be a there will be, let's say that we had some library that was void just for a voice over I P. And he was, they would be on the rest side, so they would be void the voip crate. Then on the sea side, that might be lib, void this probably a bit a name, but okay, so if that's those are what the A P S exposed. However, the actual linking of the two sides is usually defined in on the rust side as the second crate called dash sits.

So whip dash is why is which will in read all of the sea hear files with a toko bygone which you mentioned before, in generate corresponding structure on the seas on the rest side and use unsafe er a lot and all of the unsafe code will be tucked into this dash thing and the six crates job is to expose a and and it's so been easy to use a, and the easy to use abi is actually defined in the other crude. So relatively common pattern is to start with the A, B, I on the right side that you want to use, then you define an intermediary, create that uses the A P, I that must use. But IT exposes something nice and or nice enough.

And your job will be to try and provide some sort of context struct, probably through a global variable like in, but I might not be IT might be an extra perimeter of you can speak when in this somehow we're by and it's again, it's this one a typical thing. If it's if it's not none now, then we need to um then we need to. We consider the Operation has failed and as usually we discuss everything else.

And unfortunately, when you are navigating these two worlds, we can't push rest into IT into some other world. We need to exactly you when rust is pretty ing to be see IT needs to use seas conventions. I'm very, very curious as to whether or not anyone listening. Actually, here's something had a bit of suggestion because I think that this is the kind of discussion with people who do know a lot about this area. I have very strong opinions and a very, very interesting in to hear.

okay. I think with that rather well. Thank you. I'm really glad we did this and hope that helps others like me. Was there anything that we missed that you'd like to mention?

No, I just the other. The only thing would be if you're having trouble with russ to give yourself a breather and essentially allow your body and your brain to absorb the language piece by peace. IT introduces a lot of semantics that are different than other languages, and rust can feel very strict, and in some cases, peden's. And I think that that's because IT applies safety different rules than what you're used to. And so IT will take time for your your brain to kind of adjust and give yourself be patient with yourself as you learn IT.

Well, people can follow on twitter. So on the other way, you'd like them to get in touch for yeah .

look if you're off twitter or ex. Um i'm also I messed on and also youtube. I've increasingly i'm now making my my content available youtube and that's a very good way to follow me if you like, worked examples because about once every couple of weeks I put on a live stream where we go through a small exercise and implemented, I try to fumble way through and he comply there that that appear yeah.

i've watched some at those in china and really good thanks for doing this. Thanks for coming on. The show has been a real pleasure. This is govern Henry for a software engineer. Radio, thank you for listening.

Thanks for listening. S, C, radio, an educational program brought you by atter police software magazine. For more about the podcast, including other episodes, visit our website at S E dash radio dot to provide feedback.

You can comment on each episode on the website or reach us on linked in facebook, twitter or through our slack channel s radio that slack dark com. You can also email us at team at s dash radio dot net, this in all other episodes of us radio is licensed, created comments, license two point five. Thanks for listening.