[{"data":1,"prerenderedAt":5407},["ShallowReactive",2],{"/engineering-logs/how-one-little-thing-turned-into-trypema-v2":3,"/engineering-logs/how-one-little-thing-turned-into-trypema-v2--related":256},{"id":4,"title":5,"author":6,"body":7,"date":238,"description":239,"extension":240,"image_url":194,"meta":241,"navigation":242,"original_url":243,"path":244,"readTime":245,"seo":246,"stem":247,"tags":248,"__hash__":255},"engineeringLogs/engineering-logs/how-one-little-thing-turned-into-trypema-v2.md","How One New Feature in Trypema Turned Into a Major Version Release","David Oyinbo",{"type":8,"value":9,"toc":230},"minimark",[10,16,21,26,44,47,50,53,56,59,64,71,83,86,89,92,96,101,108,111,140,143,146,149,153,170,175,178,190,195,198,202,205,208,211],[11,12],"content-time-detail",{"className":13,"date":15},[14],"mb-8","2026-07-21",[17,18,20],"h1",{"id":19},"how-one-new-feature-in-trypema-turned-into-a-major-version-release","How one new feature in Trypema turned into a major version release",[22,23],"div",{"className":24},[25],"mb-4",[27,28,29,30,37,38,43],"p",{},"I'm happy to announce that the ",[31,32,36],"a",{"href":33,"rel":34},"https://trypema.davidoyinbo.com/",[35],"nofollow","Trypema"," rate limiter now has a cleaner API. It all started when I wanted to include a new feature into ",[31,39,42],{"href":40,"rel":41},"http://useceleris.com/",[35],"Celeris"," (the platform I've been rambling about for the past year). While we have our normal rate limiter working perfectly, there are still some places where it isn't perfect. For instance, we have a per-month rate limiter for free accounts, if we have an issue with redis (for instance, a cluster outage), we wouldn't want to clear all the data within the redis instance or rely on stale data which is what prompted the features that would be discussed here.",[22,45],{"className":46},[25],[27,48,49],{},"For a better background on the problem, I would explain how the current rate limiter works. Most rate limits we have on the platform work with a sliding window algorithm with the sliding window being 6 seconds. If we lose all the traffic data in redis, the cost of this won't be high. It just means we are resetting all rate limits.",[22,51],{"className":52},[25],[27,54,55],{},"But there is an issue with our longer termed rate limits. Namely, the monthly message limit for free accounts. While our philosophy is to store ephemeral data in redis, we need a mechanism to account for missing data for this longer termed rate limits. If the window is 1 month, we can't just ignore what has happened in the past one month and reset the limit as we did the other limits.",[22,57],{"className":58},[14],[60,61,63],"h2",{"id":62},"solution-1-just-check-if-we-have-anything-in-redis-for-that-key","Solution 1: Just check if we have anything in redis for that key",[65,66],"content-image",{"alt":67,"className":68,"image":70},"A Redis read returning state that may be live or stale",[69],"my-10","/engineering-logs/how-one-little-thing-turned-into-trypema-v2/read-state.webp",[27,72,73,74,78,79,82],{},"This solution is simple, when we are about to create a server for any channel involving the free account, we check the rate limiter for that key and see if we already have something in it. This is why I introduced the ",[75,76,77],"code",{},"get",", and ",[75,80,81],{},"get_estimate"," functions in the providers (local, redis and hybrid). While this seems to solve the problem, it seems to ignore a critical issue, it assumed when we have an issue with our redis cluster, we delete all the data within it. Given that redis can now store data to disk, an extended period of outage would still mean that we can retrieve data from the stale cache, and since it would still be in the window, we would interpret it as valid. This brings us to the second solution, more like something to build on top of this.",[22,84],{"className":85},[25],[27,87,88],{},"ps: Even though this method isn't what I later went with, I chose to still include it in new release of Trypema since someone might find it useful.",[22,90],{"className":91},[14],[60,93,95],{"id":94},"next-layer-priming-redis-with-the-data-we-want","Next layer: priming redis with the data we want",[65,97],{"alt":98,"className":99,"image":100},"Durable usage safely priming Redis while live traffic continues",[69],"/engineering-logs/how-one-little-thing-turned-into-trypema-v2/safe-priming.webp",[27,102,103,104,107],{},"Our long term usage data is not stored in redis, but in a separate database. We can't just use the redis client to get the data, because we don't know if the data is stale or not. Instead, when we are about to create the channel server, we would prime the system. It is very simple, we just get the usage data from our more durable datastore for the past month, then set the free account's usage to that value. Hence, why the ",[75,105,106],{},"set"," functions was introduced in the providers.",[22,109],{"className":110},[25],[27,112,113,114,117,118,121,122,125,126,125,129,125,132,135,136,139],{},"This didn't fix race conditions though, since we sync our usage data into the persistent store every 30 seconds to 1 minute, it means the priming logic can run for a channel server while another has already done that and is increasing the monthly usage in redis. If the interleving priming logic sets the value, we basically lose everything in between. So, I introduced the ",[75,115,116],{},"set_if_smaller"," function to the providers to set the value only if the value in redis is smaller than the one I'm about to set into it. Since other people can have different conditions, it was updated to a generic ",[75,119,120],{},"set_if"," function that takes in the condition for setting the value. Which can be ",[75,123,124],{},"Eq",", ",[75,127,128],{},"Lt",[75,130,131],{},"Gt",[75,133,134],{},"Ne",", or ",[75,137,138],{},"Always",".",[22,141],{"className":142},[25],[27,144,145],{},"And voila, that was the solution in my case.",[22,147],{"className":148},[14],[60,150,152],{"id":151},"the-next-things","The next things",[27,154,155,156,159,160,162,163,166,167,169],{},"While I was at it, I also added a few more features to the set function and called it ",[75,157,158],{},"set_if_preserve_history",". This is because if you want to change the value of the window (particularly reducing it, or increasing without resetting the window). You might not want to reset the whole window. So, the previous ",[75,161,120],{},", function was adjusted to do a ",[75,164,165],{},"HistoryUpdateMode::Replace",", which means it resets the whole history and sets the value in a single bucket set to now. ",[75,168,158],{}," on the other hand respects the previous history that already exists and you can tell it to either preserve the latest updates (it will mutate the farthest buckets in the windows first then work its way to the latest), or preserve the oldest (it would start its mutation from newest buckets to oldest buckets).",[65,171],{"alt":172,"className":173,"image":174},"A conditional comparison choosing replacement or history preservation",[69],"/projects/trypema-rate-limiter/conditional-updates.webp",[22,176],{"className":177},[25],[27,179,180,181,184,185,139],{},"While these didn't warrant a major version bump, they are still worth mentioning. There were naming conventions that I wasn't really happy with and the bigger issue was that when you create a ",[75,182,183],{},"RateLimiter"," in the v1, it basically starts all the providers. This is not ideal, since you might want to start only the ones you need. So, I made the providers (local, redis and hybrid) separate with fairly consistent builder patterns. There were other changes though, you can see the ",[31,186,189],{"href":187,"rel":188},"https://trypema.davidoyinbo.com/changelog/v2-0-0",[35],"full changelog here",[65,191],{"alt":192,"className":193,"image":194},"Migration from the v1 facade to independent v2 providers",[69],"/projects/trypema-rate-limiter/v2-migration.webp",[22,196],{"className":197},[14],[60,199,201],{"id":200},"closing-notes","Closing notes",[22,203],{"className":204},[25],[27,206,207],{},"I thank thee for partaking in the reading of this my diary (or logs). I hope you enjoyed it. Adios!",[22,209],{"className":210},[25],[27,212,213,214,218,219,224,225,139],{},"Read the ",[31,215,217],{"href":33,"rel":216},[35],"v2 documentation",", the\n",[31,220,223],{"href":221,"rel":222},"https://docs.rs/trypema",[35],"API reference",", or the\n",[31,226,229],{"href":227,"rel":228},"https://github.com/dev-davexoyinbo/trypema",[35],"source",{"title":231,"searchDepth":232,"depth":232,"links":233},"",2,[234,235,236,237],{"id":62,"depth":232,"text":63},{"id":94,"depth":232,"text":95},{"id":151,"depth":232,"text":152},{"id":200,"depth":232,"text":201},"2026-07-21T00:00:00.000Z","How solving persistent monthly rate limits for Celeris led to live reads, safe conditional updates, history preservation, independent providers, and Trypema v2.","md",{},true,"https://davidoyinbo.com/engineering-logs/how-one-little-thing-turned-into-trypema-v2","/engineering-logs/how-one-little-thing-turned-into-trypema-v2","5 min",{"title":5,"description":239},"engineering-logs/how-one-little-thing-turned-into-trypema-v2",[249,250,251,252,253,254],"rust","rate-limiting","redis","distributed-systems","celeris","engineering","hRfAox1wUWKsvVZlQbeUU5e-3PX9vRZtkQzQhTGGbMk",[257,3230,3524],{"id":258,"title":259,"author":6,"body":260,"date":3216,"description":3217,"extension":240,"image_url":3218,"meta":3219,"navigation":242,"original_url":3193,"path":3220,"readTime":3221,"seo":3222,"stem":3223,"tags":3224,"__hash__":3229},"engineeringLogs/engineering-logs/embracing-perfection-rust.md","Embracing Perfection: A Journey into Rust Programming",{"type":8,"value":261,"toc":3201},[262,267,270,273,277,281,284,288,291,294,298,301,304,309,312,316,321,324,327,333,336,473,476,486,489,493,496,499,504,507,699,702,731,734,738,741,744,748,751,754,759,762,953,956,980,983,987,990,993,998,1001,1316,1319,1349,1352,1356,1359,1362,1365,1370,1373,1495,1498,1508,1511,1516,1519,1648,1651,1664,1667,1670,1674,1677,1680,1685,1688,1881,1884,1895,1898,1903,1906,2005,2008,2022,2025,2028,2032,2035,2038,2043,2046,2152,2155,2175,2178,2183,2186,2411,2414,2448,2451,2456,2459,2572,2575,2601,2604,2607,2611,2614,2617,2620,2625,2628,2713,2716,2744,2747,2750,2763,2766,2770,2773,2776,2780,2783,2788,2791,3113,3116,3128,3148,3154,3160,3163,3167,3170,3173,3176,3179,3182,3185,3197],[11,263],{"className":264,"date":266},[265],"mb-2","2023-06-20",[17,268,259],{"id":269},"embracing-perfection-a-journey-into-rust-programming",[27,271,272],{},"Embarking on the journey of learning Rust is like stepping into a world that demands perfection. While it may not be the easiest language to master, Rust offers a unique set of features and concepts that push developers to consider every aspect of their code.",[22,274],{"className":275},[276],"mb-3",[278,279],"tag-list",{":tags":280},"[\"Rust\", \"Programming\", \"Backend\", \"Systems\", \"Memory Safety\"]",[22,282],{"className":283},[14],[60,285,287],{"id":286},"overview","Overview",[27,289,290],{},"In this article, we will explore some of the core features and concepts that make Rust a powerful and compelling language for developers. Whether you're a beginner or an experienced programmer, these insights will help you understand and appreciate the value of Rust's ownership system, pattern matching, lifetimes, and concurrency primitives.",[22,292],{"className":293},[14],[60,295,297],{"id":296},"_1-embracing-functional-and-object-oriented-concepts-in-rust","1. Embracing Functional and Object-Oriented Concepts in Rust",[27,299,300],{},"Rust is a versatile language that combines elements of functional programming and object-oriented programming (OOP) paradigms. While it is not a strictly functional or purely OOP language, Rust provides powerful features and concepts that allow developers to embrace functional and OOP principles in their code. Let's explore how Rust handles these concepts and empowers developers to write expressive and modular code.",[22,302],{"className":303},[14],[305,306,308],"h3",{"id":307},"functional-programming-in-rust","Functional Programming in Rust",[27,310,311],{},"Functional programming emphasizes immutability, pure functions, and higher-order functions. Although Rust is not a pure functional language, it offers several features that align with functional programming principles.",[22,313],{"className":314},[315],"mb-6",[317,318,320],"h4",{"id":319},"immutability-and-functional-concepts","Immutability and Functional Concepts",[27,322,323],{},"Rust encourages immutability by default. Variables are immutable by default, and you need to explicitly mark them as mutable when necessary. This approach aligns with functional programming's emphasis on immutability to avoid unintended side effects and improve code clarity.",[22,325],{"className":326},[14],[27,328,329],{},[330,331,332],"strong",{},"Example: Immutability in Rust",[22,334],{"className":335},[25],[337,338,342],"pre",{"className":339,"code":340,"filename":341,"language":249,"meta":231,"style":231},"language-rust shiki shiki-themes github-dark","fn main() {\n    let x = 5; // Immutable binding\n    let y = {\n        let x = 2; // Shadowing with new binding\n        x + 1\n    };\n    println!(\"x: {}\", x); // Prints 5\n    println!(\"y: {}\", y); // Prints 3\n}\n","main.rs",[75,343,344,361,383,396,414,426,432,451,467],{"__ignoreMap":231},[345,346,349,353,357],"span",{"class":347,"line":348},"line",1,[345,350,352],{"class":351},"snl16","fn",[345,354,356],{"class":355},"svObZ"," main",[345,358,360],{"class":359},"s95oV","() {\n",[345,362,363,366,369,372,376,379],{"class":347,"line":232},[345,364,365],{"class":351},"    let",[345,367,368],{"class":359}," x ",[345,370,371],{"class":351},"=",[345,373,375],{"class":374},"sDLfK"," 5",[345,377,378],{"class":359},"; ",[345,380,382],{"class":381},"sAwPA","// Immutable binding\n",[345,384,386,388,391,393],{"class":347,"line":385},3,[345,387,365],{"class":351},[345,389,390],{"class":359}," y ",[345,392,371],{"class":351},[345,394,395],{"class":359}," {\n",[345,397,399,402,404,406,409,411],{"class":347,"line":398},4,[345,400,401],{"class":351},"        let",[345,403,368],{"class":359},[345,405,371],{"class":351},[345,407,408],{"class":374}," 2",[345,410,378],{"class":359},[345,412,413],{"class":381},"// Shadowing with new binding\n",[345,415,417,420,423],{"class":347,"line":416},5,[345,418,419],{"class":359},"        x ",[345,421,422],{"class":351},"+",[345,424,425],{"class":374}," 1\n",[345,427,429],{"class":347,"line":428},6,[345,430,431],{"class":359},"    };\n",[345,433,435,438,441,445,448],{"class":347,"line":434},7,[345,436,437],{"class":355},"    println!",[345,439,440],{"class":359},"(",[345,442,444],{"class":443},"sU2Wk","\"x: {}\"",[345,446,447],{"class":359},", x); ",[345,449,450],{"class":381},"// Prints 5\n",[345,452,454,456,458,461,464],{"class":347,"line":453},8,[345,455,437],{"class":355},[345,457,440],{"class":359},[345,459,460],{"class":443},"\"y: {}\"",[345,462,463],{"class":359},", y); ",[345,465,466],{"class":381},"// Prints 3\n",[345,468,470],{"class":347,"line":469},9,[345,471,472],{"class":359},"}\n",[22,474],{"className":475},[25],[27,477,478,479,482,483,485],{},"In this example, the variable ",[75,480,481],{},"x"," is initially bound to the value 5. Inside the block, we create a new binding, also named ",[75,484,481],{},", which shadows the outer binding. This demonstrates Rust's support for functional-style immutability through shadowing.",[22,487],{"className":488},[315],[317,490,492],{"id":491},"higher-order-functions","Higher-Order Functions",[27,494,495],{},"Rust supports higher-order functions, allowing you to pass functions as arguments or return them from other functions. This enables powerful abstractions and functional composition.",[22,497],{"className":498},[14],[27,500,501],{},[330,502,503],{},"Example: Higher-Order Functions in Rust",[22,505],{"className":506},[25],[337,508,510],{"className":339,"code":509,"filename":341,"language":249,"meta":231,"style":231},"fn apply_twice\u003CF>(f: F, x: i32) -> i32\nwhere\n    F: Fn(i32) -> i32,\n{\n    f(f(x))\n}\n\nfn add_one(x: i32) -> i32 {\n    x + 1\n}\n\nfn main() {\n    let result = apply_twice(add_one, 2);\n    println!(\"Result: {}\", result); // Prints 4\n}\n",[75,511,512,551,556,580,585,598,602,607,629,638,643,648,657,678,694],{"__ignoreMap":231},[345,513,514,516,519,522,525,528,531,534,537,539,542,545,548],{"class":347,"line":348},[345,515,352],{"class":351},[345,517,518],{"class":355}," apply_twice",[345,520,521],{"class":359},"\u003C",[345,523,524],{"class":355},"F",[345,526,527],{"class":359},">(f",[345,529,530],{"class":351},":",[345,532,533],{"class":355}," F",[345,535,536],{"class":359},", x",[345,538,530],{"class":351},[345,540,541],{"class":355}," i32",[345,543,544],{"class":359},") ",[345,546,547],{"class":351},"->",[345,549,550],{"class":355}," i32\n",[345,552,553],{"class":347,"line":232},[345,554,555],{"class":351},"where\n",[345,557,558,561,563,566,568,571,573,575,577],{"class":347,"line":385},[345,559,560],{"class":355},"    F",[345,562,530],{"class":351},[345,564,565],{"class":355}," Fn",[345,567,440],{"class":359},[345,569,570],{"class":355},"i32",[345,572,544],{"class":359},[345,574,547],{"class":351},[345,576,541],{"class":355},[345,578,579],{"class":359},",\n",[345,581,582],{"class":347,"line":398},[345,583,584],{"class":359},"{\n",[345,586,587,590,592,595],{"class":347,"line":416},[345,588,589],{"class":355},"    f",[345,591,440],{"class":359},[345,593,594],{"class":355},"f",[345,596,597],{"class":359},"(x))\n",[345,599,600],{"class":347,"line":428},[345,601,472],{"class":359},[345,603,604],{"class":347,"line":434},[345,605,606],{"emptyLinePlaceholder":242},"\n",[345,608,609,611,614,617,619,621,623,625,627],{"class":347,"line":453},[345,610,352],{"class":351},[345,612,613],{"class":355}," add_one",[345,615,616],{"class":359},"(x",[345,618,530],{"class":351},[345,620,541],{"class":355},[345,622,544],{"class":359},[345,624,547],{"class":351},[345,626,541],{"class":355},[345,628,395],{"class":359},[345,630,631,634,636],{"class":347,"line":469},[345,632,633],{"class":359},"    x ",[345,635,422],{"class":351},[345,637,425],{"class":374},[345,639,641],{"class":347,"line":640},10,[345,642,472],{"class":359},[345,644,646],{"class":347,"line":645},11,[345,647,606],{"emptyLinePlaceholder":242},[345,649,651,653,655],{"class":347,"line":650},12,[345,652,352],{"class":351},[345,654,356],{"class":355},[345,656,360],{"class":359},[345,658,660,662,665,667,669,672,675],{"class":347,"line":659},13,[345,661,365],{"class":351},[345,663,664],{"class":359}," result ",[345,666,371],{"class":351},[345,668,518],{"class":355},[345,670,671],{"class":359},"(add_one, ",[345,673,674],{"class":374},"2",[345,676,677],{"class":359},");\n",[345,679,681,683,685,688,691],{"class":347,"line":680},14,[345,682,437],{"class":355},[345,684,440],{"class":359},[345,686,687],{"class":443},"\"Result: {}\"",[345,689,690],{"class":359},", result); ",[345,692,693],{"class":381},"// Prints 4\n",[345,695,697],{"class":347,"line":696},15,[345,698,472],{"class":359},[22,700],{"className":701},[25],[27,703,704,705,708,709,711,712,714,715,717,718,720,721,723,724,727,728,730],{},"In this example, the ",[75,706,707],{},"apply_twice"," function takes a closure ",[75,710,594],{}," and applies it twice to the argument ",[75,713,481],{},". The closure ",[75,716,524],{}," is a higher-order function that takes an ",[75,719,570],{}," argument and returns an ",[75,722,570],{},". We pass the ",[75,725,726],{},"add_one"," function as an argument to ",[75,729,707],{},", demonstrating the ability to pass functions as arguments and apply them within Rust.",[22,732],{"className":733},[315],[305,735,737],{"id":736},"object-oriented-programming-in-rust","Object-Oriented Programming in Rust",[27,739,740],{},"While Rust does not have traditional class-based OOP like languages such as Java or C++, it provides features that allow developers to achieve object-oriented designs and encapsulation.",[22,742],{"className":743},[315],[317,745,747],{"id":746},"structs-and-methods","Structs and Methods",[27,749,750],{},"Rust uses structs to define custom data types and associated methods. Methods are functions defined within the context of a struct, enabling data encapsulation and object-like behavior.",[22,752],{"className":753},[14],[27,755,756],{},[330,757,758],{},"Example: Structs and Methods in Rust",[22,760],{"className":761},[25],[337,763,765],{"className":339,"code":764,"filename":341,"language":249,"meta":231,"style":231},"struct Rectangle {\n    width: u32,\n    height: u32,\n}\n\nimpl Rectangle {\n    fn area(&self) -> u32 {\n        self.width * self.height\n    }\n}\n\nfn main() {\n    let rect = Rectangle {\n        width: 10,\n        height: 5,\n    };\n    println!(\"Area: {}\", rect.area()); // Prints 50\n}\n",[75,766,767,777,789,800,804,808,817,841,862,867,871,875,883,896,908,919,924,948],{"__ignoreMap":231},[345,768,769,772,775],{"class":347,"line":348},[345,770,771],{"class":351},"struct",[345,773,774],{"class":355}," Rectangle",[345,776,395],{"class":359},[345,778,779,782,784,787],{"class":347,"line":232},[345,780,781],{"class":359},"    width",[345,783,530],{"class":351},[345,785,786],{"class":355}," u32",[345,788,579],{"class":359},[345,790,791,794,796,798],{"class":347,"line":385},[345,792,793],{"class":359},"    height",[345,795,530],{"class":351},[345,797,786],{"class":355},[345,799,579],{"class":359},[345,801,802],{"class":347,"line":398},[345,803,472],{"class":359},[345,805,806],{"class":347,"line":416},[345,807,606],{"emptyLinePlaceholder":242},[345,809,810,813,815],{"class":347,"line":428},[345,811,812],{"class":351},"impl",[345,814,774],{"class":355},[345,816,395],{"class":359},[345,818,819,822,825,827,830,833,835,837,839],{"class":347,"line":434},[345,820,821],{"class":351},"    fn",[345,823,824],{"class":355}," area",[345,826,440],{"class":359},[345,828,829],{"class":351},"&",[345,831,832],{"class":374},"self",[345,834,544],{"class":359},[345,836,547],{"class":351},[345,838,786],{"class":355},[345,840,395],{"class":359},[345,842,843,846,848,851,854,857,859],{"class":347,"line":453},[345,844,845],{"class":374},"        self",[345,847,139],{"class":351},[345,849,850],{"class":359},"width ",[345,852,853],{"class":351},"*",[345,855,856],{"class":374}," self",[345,858,139],{"class":351},[345,860,861],{"class":359},"height\n",[345,863,864],{"class":347,"line":469},[345,865,866],{"class":359},"    }\n",[345,868,869],{"class":347,"line":640},[345,870,472],{"class":359},[345,872,873],{"class":347,"line":645},[345,874,606],{"emptyLinePlaceholder":242},[345,876,877,879,881],{"class":347,"line":650},[345,878,352],{"class":351},[345,880,356],{"class":355},[345,882,360],{"class":359},[345,884,885,887,890,892,894],{"class":347,"line":659},[345,886,365],{"class":351},[345,888,889],{"class":359}," rect ",[345,891,371],{"class":351},[345,893,774],{"class":355},[345,895,395],{"class":359},[345,897,898,901,903,906],{"class":347,"line":680},[345,899,900],{"class":359},"        width",[345,902,530],{"class":351},[345,904,905],{"class":374}," 10",[345,907,579],{"class":359},[345,909,910,913,915,917],{"class":347,"line":696},[345,911,912],{"class":359},"        height",[345,914,530],{"class":351},[345,916,375],{"class":374},[345,918,579],{"class":359},[345,920,922],{"class":347,"line":921},16,[345,923,431],{"class":359},[345,925,927,929,931,934,937,939,942,945],{"class":347,"line":926},17,[345,928,437],{"class":355},[345,930,440],{"class":359},[345,932,933],{"class":443},"\"Area: {}\"",[345,935,936],{"class":359},", rect",[345,938,139],{"class":351},[345,940,941],{"class":355},"area",[345,943,944],{"class":359},"()); ",[345,946,947],{"class":381},"// Prints 50\n",[345,949,951],{"class":347,"line":950},18,[345,952,472],{"class":359},[22,954],{"className":955},[25],[27,957,958,959,962,963,966,967,970,971,973,974,976,977,979],{},"In this example, we define a ",[75,960,961],{},"Rectangle"," struct with ",[75,964,965],{},"width"," and ",[75,968,969],{},"height"," fields. We implement an associated method ",[75,972,941],{}," for the struct, which calculates and returns the area of the rectangle. By using the ",[75,975,812],{}," block, we define the implementation of the methods associated with the ",[75,978,961],{}," struct.",[22,981],{"className":982},[315],[317,984,986],{"id":985},"traits-and-polymorphism","Traits and Polymorphism",[27,988,989],{},"Rust's trait system provides a way to achieve polymorphism and code reuse, similar to interfaces in OOP languages. Traits define behavior that types can implement, allowing for dynamic dispatch and runtime polymorphism.",[22,991],{"className":992},[14],[27,994,995],{},[330,996,997],{},"Example: Traits and Polymorphism in Rust",[22,999],{"className":1000},[25],[337,1002,1004],{"className":339,"code":1003,"filename":341,"language":249,"meta":231,"style":231},"trait Animal {\n    fn sound(&self);\n}\n\nstruct Dog;\nstruct Cat;\n\nimpl Animal for Dog {\n    fn sound(&self) {\n        println!(\"Woof!\");\n    }\n}\n\nimpl Animal for Cat {\n    fn sound(&self) {\n        println!(\"Meow!\");\n    }\n}\n\nfn main() {\n    let dog: Dog = Dog;\n    let cat: Cat = Cat;\n    \n    let animals: Vec\u003CBox\u003Cdyn Animal>> = vec![Box::new(dog), Box::new(cat)];\n    \n    for animal in animals {\n        animal.sound();\n    }\n}\n",[75,1005,1006,1016,1031,1035,1039,1049,1058,1062,1075,1090,1102,1106,1110,1114,1126,1140,1151,1155,1159,1164,1173,1192,1210,1216,1272,1277,1292,1306,1311],{"__ignoreMap":231},[345,1007,1008,1011,1014],{"class":347,"line":348},[345,1009,1010],{"class":351},"trait",[345,1012,1013],{"class":355}," Animal",[345,1015,395],{"class":359},[345,1017,1018,1020,1023,1025,1027,1029],{"class":347,"line":232},[345,1019,821],{"class":351},[345,1021,1022],{"class":355}," sound",[345,1024,440],{"class":359},[345,1026,829],{"class":351},[345,1028,832],{"class":374},[345,1030,677],{"class":359},[345,1032,1033],{"class":347,"line":385},[345,1034,472],{"class":359},[345,1036,1037],{"class":347,"line":398},[345,1038,606],{"emptyLinePlaceholder":242},[345,1040,1041,1043,1046],{"class":347,"line":416},[345,1042,771],{"class":351},[345,1044,1045],{"class":355}," Dog",[345,1047,1048],{"class":359},";\n",[345,1050,1051,1053,1056],{"class":347,"line":428},[345,1052,771],{"class":351},[345,1054,1055],{"class":355}," Cat",[345,1057,1048],{"class":359},[345,1059,1060],{"class":347,"line":434},[345,1061,606],{"emptyLinePlaceholder":242},[345,1063,1064,1066,1068,1071,1073],{"class":347,"line":453},[345,1065,812],{"class":351},[345,1067,1013],{"class":355},[345,1069,1070],{"class":351}," for",[345,1072,1045],{"class":355},[345,1074,395],{"class":359},[345,1076,1077,1079,1081,1083,1085,1087],{"class":347,"line":469},[345,1078,821],{"class":351},[345,1080,1022],{"class":355},[345,1082,440],{"class":359},[345,1084,829],{"class":351},[345,1086,832],{"class":374},[345,1088,1089],{"class":359},") {\n",[345,1091,1092,1095,1097,1100],{"class":347,"line":640},[345,1093,1094],{"class":355},"        println!",[345,1096,440],{"class":359},[345,1098,1099],{"class":443},"\"Woof!\"",[345,1101,677],{"class":359},[345,1103,1104],{"class":347,"line":645},[345,1105,866],{"class":359},[345,1107,1108],{"class":347,"line":650},[345,1109,472],{"class":359},[345,1111,1112],{"class":347,"line":659},[345,1113,606],{"emptyLinePlaceholder":242},[345,1115,1116,1118,1120,1122,1124],{"class":347,"line":680},[345,1117,812],{"class":351},[345,1119,1013],{"class":355},[345,1121,1070],{"class":351},[345,1123,1055],{"class":355},[345,1125,395],{"class":359},[345,1127,1128,1130,1132,1134,1136,1138],{"class":347,"line":696},[345,1129,821],{"class":351},[345,1131,1022],{"class":355},[345,1133,440],{"class":359},[345,1135,829],{"class":351},[345,1137,832],{"class":374},[345,1139,1089],{"class":359},[345,1141,1142,1144,1146,1149],{"class":347,"line":921},[345,1143,1094],{"class":355},[345,1145,440],{"class":359},[345,1147,1148],{"class":443},"\"Meow!\"",[345,1150,677],{"class":359},[345,1152,1153],{"class":347,"line":926},[345,1154,866],{"class":359},[345,1156,1157],{"class":347,"line":950},[345,1158,472],{"class":359},[345,1160,1162],{"class":347,"line":1161},19,[345,1163,606],{"emptyLinePlaceholder":242},[345,1165,1167,1169,1171],{"class":347,"line":1166},20,[345,1168,352],{"class":351},[345,1170,356],{"class":355},[345,1172,360],{"class":359},[345,1174,1176,1178,1181,1183,1185,1188,1190],{"class":347,"line":1175},21,[345,1177,365],{"class":351},[345,1179,1180],{"class":359}," dog",[345,1182,530],{"class":351},[345,1184,1045],{"class":355},[345,1186,1187],{"class":351}," =",[345,1189,1045],{"class":355},[345,1191,1048],{"class":359},[345,1193,1195,1197,1200,1202,1204,1206,1208],{"class":347,"line":1194},22,[345,1196,365],{"class":351},[345,1198,1199],{"class":359}," cat",[345,1201,530],{"class":351},[345,1203,1055],{"class":355},[345,1205,1187],{"class":351},[345,1207,1055],{"class":355},[345,1209,1048],{"class":359},[345,1211,1213],{"class":347,"line":1212},23,[345,1214,1215],{"class":359},"    \n",[345,1217,1219,1221,1224,1226,1229,1231,1234,1236,1239,1241,1244,1246,1249,1252,1254,1257,1260,1263,1265,1267,1269],{"class":347,"line":1218},24,[345,1220,365],{"class":351},[345,1222,1223],{"class":359}," animals",[345,1225,530],{"class":351},[345,1227,1228],{"class":355}," Vec",[345,1230,521],{"class":359},[345,1232,1233],{"class":355},"Box",[345,1235,521],{"class":359},[345,1237,1238],{"class":351},"dyn",[345,1240,1013],{"class":355},[345,1242,1243],{"class":359},">> ",[345,1245,371],{"class":351},[345,1247,1248],{"class":355}," vec!",[345,1250,1251],{"class":359},"[",[345,1253,1233],{"class":355},[345,1255,1256],{"class":351},"::",[345,1258,1259],{"class":355},"new",[345,1261,1262],{"class":359},"(dog), ",[345,1264,1233],{"class":355},[345,1266,1256],{"class":351},[345,1268,1259],{"class":355},[345,1270,1271],{"class":359},"(cat)];\n",[345,1273,1275],{"class":347,"line":1274},25,[345,1276,1215],{"class":359},[345,1278,1280,1283,1286,1289],{"class":347,"line":1279},26,[345,1281,1282],{"class":351},"    for",[345,1284,1285],{"class":359}," animal ",[345,1287,1288],{"class":351},"in",[345,1290,1291],{"class":359}," animals {\n",[345,1293,1295,1298,1300,1303],{"class":347,"line":1294},27,[345,1296,1297],{"class":359},"        animal",[345,1299,139],{"class":351},[345,1301,1302],{"class":355},"sound",[345,1304,1305],{"class":359},"();\n",[345,1307,1309],{"class":347,"line":1308},28,[345,1310,866],{"class":359},[345,1312,1314],{"class":347,"line":1313},29,[345,1315,472],{"class":359},[22,1317],{"className":1318},[25],[27,1320,1321,1322,1325,1326,1328,1329,1331,1332,966,1335,1338,1339,1341,1342,1345,1346,1348],{},"In this example, we define the ",[75,1323,1324],{},"Animal"," trait with a method ",[75,1327,1302],{},". We implement the ",[75,1330,1324],{}," trait for the ",[75,1333,1334],{},"Dog",[75,1336,1337],{},"Cat"," structs, each providing their own implementation of the ",[75,1340,1302],{}," method. We create a vector of boxed ",[75,1343,1344],{},"dyn Animal"," trait objects and iterate over them, calling the ",[75,1347,1302],{}," method dynamically at runtime.",[22,1350],{"className":1351},[14],[60,1353,1355],{"id":1354},"_2-ownership-and-borrowing","2. Ownership and Borrowing",[27,1357,1358],{},"Rust's ownership and borrowing system can be likened to a set of buckets representing different scopes. Each bucket represents a local scope, and the entities within the bucket are dropped or deallocated when the bucket or local scope goes out of scope. Understanding this analogy can help grasp the concepts of ownership and borrowing in Rust.",[27,1360,1361],{},"Imagine we have a bucket representing the main function scope. Inside this bucket, we can place entities, which can be either moved or borrowed when a new bucket (such as a function) is created. Let's explore these concepts further:",[22,1363],{"className":1364},[14],[27,1366,1367],{},[330,1368,1369],{},"Example 1: Ownership (Moving)",[22,1371],{"className":1372},[25],[337,1374,1376],{"className":339,"code":1375,"filename":341,"language":249,"meta":231,"style":231},"fn main() {\n    let string = String::from(\"Hello\");\n    let new_string = take_ownership(string);\n    // The string is moved to the `take_ownership` function and no longer accessible here.\n    println!(\"New string: {}\", new_string);\n}\n\nfn take_ownership(s: String) -> String {\n    // The ownership of the `s` string is transferred to this function.\n    // We can perform operations on `s` without affecting the original string.\n    s + \" World!\"\n}\n",[75,1377,1378,1386,1410,1425,1430,1442,1446,1450,1471,1476,1481,1491],{"__ignoreMap":231},[345,1379,1380,1382,1384],{"class":347,"line":348},[345,1381,352],{"class":351},[345,1383,356],{"class":355},[345,1385,360],{"class":359},[345,1387,1388,1390,1393,1395,1398,1400,1403,1405,1408],{"class":347,"line":232},[345,1389,365],{"class":351},[345,1391,1392],{"class":359}," string ",[345,1394,371],{"class":351},[345,1396,1397],{"class":355}," String",[345,1399,1256],{"class":351},[345,1401,1402],{"class":355},"from",[345,1404,440],{"class":359},[345,1406,1407],{"class":443},"\"Hello\"",[345,1409,677],{"class":359},[345,1411,1412,1414,1417,1419,1422],{"class":347,"line":385},[345,1413,365],{"class":351},[345,1415,1416],{"class":359}," new_string ",[345,1418,371],{"class":351},[345,1420,1421],{"class":355}," take_ownership",[345,1423,1424],{"class":359},"(string);\n",[345,1426,1427],{"class":347,"line":398},[345,1428,1429],{"class":381},"    // The string is moved to the `take_ownership` function and no longer accessible here.\n",[345,1431,1432,1434,1436,1439],{"class":347,"line":416},[345,1433,437],{"class":355},[345,1435,440],{"class":359},[345,1437,1438],{"class":443},"\"New string: {}\"",[345,1440,1441],{"class":359},", new_string);\n",[345,1443,1444],{"class":347,"line":428},[345,1445,472],{"class":359},[345,1447,1448],{"class":347,"line":434},[345,1449,606],{"emptyLinePlaceholder":242},[345,1451,1452,1454,1456,1459,1461,1463,1465,1467,1469],{"class":347,"line":453},[345,1453,352],{"class":351},[345,1455,1421],{"class":355},[345,1457,1458],{"class":359},"(s",[345,1460,530],{"class":351},[345,1462,1397],{"class":355},[345,1464,544],{"class":359},[345,1466,547],{"class":351},[345,1468,1397],{"class":355},[345,1470,395],{"class":359},[345,1472,1473],{"class":347,"line":469},[345,1474,1475],{"class":381},"    // The ownership of the `s` string is transferred to this function.\n",[345,1477,1478],{"class":347,"line":640},[345,1479,1480],{"class":381},"    // We can perform operations on `s` without affecting the original string.\n",[345,1482,1483,1486,1488],{"class":347,"line":645},[345,1484,1485],{"class":359},"    s ",[345,1487,422],{"class":351},[345,1489,1490],{"class":443}," \" World!\"\n",[345,1492,1493],{"class":347,"line":650},[345,1494,472],{"class":359},[22,1496],{"className":1497},[25],[27,1499,704,1500,1503,1504,1507],{},[75,1501,1502],{},"take_ownership"," function takes ownership of the ",[75,1505,1506],{},"string"," and returns a new string. The original string is moved to the function, and it cannot be accessed in the main function afterward.",[22,1509],{"className":1510},[315],[27,1512,1513],{},[330,1514,1515],{},"Example 2: Borrowing (Referencing)",[22,1517],{"className":1518},[25],[337,1520,1522],{"className":339,"code":1521,"filename":341,"language":249,"meta":231,"style":231},"fn main() {\n    let string = String::from(\"Hello\");\n    let length = calculate_length(&string);\n    // The `string` is still accessible in the main function after borrowing.\n    println!(\"Length of {}: {}\", string, length);\n}\n\nfn calculate_length(s: &String) -> usize {\n    // The `s` parameter is a reference to the original string.\n    // We can perform operations on the borrowed string without taking ownership.\n    s.len()\n}\n",[75,1523,1524,1532,1552,1571,1576,1588,1592,1596,1621,1626,1631,1644],{"__ignoreMap":231},[345,1525,1526,1528,1530],{"class":347,"line":348},[345,1527,352],{"class":351},[345,1529,356],{"class":355},[345,1531,360],{"class":359},[345,1533,1534,1536,1538,1540,1542,1544,1546,1548,1550],{"class":347,"line":232},[345,1535,365],{"class":351},[345,1537,1392],{"class":359},[345,1539,371],{"class":351},[345,1541,1397],{"class":355},[345,1543,1256],{"class":351},[345,1545,1402],{"class":355},[345,1547,440],{"class":359},[345,1549,1407],{"class":443},[345,1551,677],{"class":359},[345,1553,1554,1556,1559,1561,1564,1566,1568],{"class":347,"line":385},[345,1555,365],{"class":351},[345,1557,1558],{"class":359}," length ",[345,1560,371],{"class":351},[345,1562,1563],{"class":355}," calculate_length",[345,1565,440],{"class":359},[345,1567,829],{"class":351},[345,1569,1570],{"class":359},"string);\n",[345,1572,1573],{"class":347,"line":398},[345,1574,1575],{"class":381},"    // The `string` is still accessible in the main function after borrowing.\n",[345,1577,1578,1580,1582,1585],{"class":347,"line":416},[345,1579,437],{"class":355},[345,1581,440],{"class":359},[345,1583,1584],{"class":443},"\"Length of {}: {}\"",[345,1586,1587],{"class":359},", string, length);\n",[345,1589,1590],{"class":347,"line":428},[345,1591,472],{"class":359},[345,1593,1594],{"class":347,"line":434},[345,1595,606],{"emptyLinePlaceholder":242},[345,1597,1598,1600,1602,1604,1606,1609,1612,1614,1616,1619],{"class":347,"line":453},[345,1599,352],{"class":351},[345,1601,1563],{"class":355},[345,1603,1458],{"class":359},[345,1605,530],{"class":351},[345,1607,1608],{"class":351}," &",[345,1610,1611],{"class":355},"String",[345,1613,544],{"class":359},[345,1615,547],{"class":351},[345,1617,1618],{"class":355}," usize",[345,1620,395],{"class":359},[345,1622,1623],{"class":347,"line":469},[345,1624,1625],{"class":381},"    // The `s` parameter is a reference to the original string.\n",[345,1627,1628],{"class":347,"line":640},[345,1629,1630],{"class":381},"    // We can perform operations on the borrowed string without taking ownership.\n",[345,1632,1633,1636,1638,1641],{"class":347,"line":645},[345,1634,1635],{"class":359},"    s",[345,1637,139],{"class":351},[345,1639,1640],{"class":355},"len",[345,1642,1643],{"class":359},"()\n",[345,1645,1646],{"class":347,"line":650},[345,1647,472],{"class":359},[22,1649],{"className":1650},[25],[27,1652,704,1653,1656,1657,1659,1660,1663],{},[75,1654,1655],{},"calculate_length"," function borrows the ",[75,1658,1506],{}," by accepting a reference (",[75,1661,1662],{},"&string","). The reference allows the function to access the string's data without taking ownership. Therefore, the original string remains accessible in the main function even after borrowing.",[27,1665,1666],{},"By distinguishing between ownership (moving) and borrowing (referencing), Rust ensures memory safety and eliminates common bugs caused by multiple owners or invalid access to data. This system encourages developers to think carefully about how data is passed between scopes and promotes efficient and safe code.",[22,1668],{"className":1669},[14],[60,1671,1673],{"id":1672},"_3-pattern-matching","3. Pattern Matching",[27,1675,1676],{},"Rust's pattern matching is a versatile tool that allows developers to handle different scenarios and deconstruct complex data structures. It provides concise and expressive syntax, enabling effective case handling and value extraction. Let's delve into the concept of pattern matching in Rust:",[22,1678],{"className":1679},[14],[27,1681,1682],{},[330,1683,1684],{},"Example 1: Matching Enums",[22,1686],{"className":1687},[25],[337,1689,1691],{"className":339,"code":1690,"filename":341,"language":249,"meta":231,"style":231},"enum Message {\n    Quit,\n    Move { x: i32, y: i32 },\n    Write(String),\n}\n\nfn process_message(msg: Message) {\n    match msg {\n        Message::Quit => {\n            println!(\"Quit message received\");\n        }\n        Message::Move { x, y } => {\n            println!(\"Move to ({}, {})\", x, y);\n        }\n        Message::Write(text) => {\n            println!(\"Write message: {}\", text);\n        }\n    }\n}\n",[75,1692,1693,1703,1710,1732,1744,1748,1752,1768,1776,1791,1803,1808,1825,1837,1841,1857,1869,1873,1877],{"__ignoreMap":231},[345,1694,1695,1698,1701],{"class":347,"line":348},[345,1696,1697],{"class":351},"enum",[345,1699,1700],{"class":355}," Message",[345,1702,395],{"class":359},[345,1704,1705,1708],{"class":347,"line":232},[345,1706,1707],{"class":355},"    Quit",[345,1709,579],{"class":359},[345,1711,1712,1715,1718,1720,1722,1725,1727,1729],{"class":347,"line":385},[345,1713,1714],{"class":355},"    Move",[345,1716,1717],{"class":359}," { x",[345,1719,530],{"class":351},[345,1721,541],{"class":355},[345,1723,1724],{"class":359},", y",[345,1726,530],{"class":351},[345,1728,541],{"class":355},[345,1730,1731],{"class":359}," },\n",[345,1733,1734,1737,1739,1741],{"class":347,"line":398},[345,1735,1736],{"class":355},"    Write",[345,1738,440],{"class":359},[345,1740,1611],{"class":355},[345,1742,1743],{"class":359},"),\n",[345,1745,1746],{"class":347,"line":416},[345,1747,472],{"class":359},[345,1749,1750],{"class":347,"line":428},[345,1751,606],{"emptyLinePlaceholder":242},[345,1753,1754,1756,1759,1762,1764,1766],{"class":347,"line":434},[345,1755,352],{"class":351},[345,1757,1758],{"class":355}," process_message",[345,1760,1761],{"class":359},"(msg",[345,1763,530],{"class":351},[345,1765,1700],{"class":355},[345,1767,1089],{"class":359},[345,1769,1770,1773],{"class":347,"line":453},[345,1771,1772],{"class":351},"    match",[345,1774,1775],{"class":359}," msg {\n",[345,1777,1778,1781,1783,1786,1789],{"class":347,"line":469},[345,1779,1780],{"class":355},"        Message",[345,1782,1256],{"class":351},[345,1784,1785],{"class":355},"Quit",[345,1787,1788],{"class":351}," =>",[345,1790,395],{"class":359},[345,1792,1793,1796,1798,1801],{"class":347,"line":640},[345,1794,1795],{"class":355},"            println!",[345,1797,440],{"class":359},[345,1799,1800],{"class":443},"\"Quit message received\"",[345,1802,677],{"class":359},[345,1804,1805],{"class":347,"line":645},[345,1806,1807],{"class":359},"        }\n",[345,1809,1810,1812,1814,1817,1820,1823],{"class":347,"line":650},[345,1811,1780],{"class":355},[345,1813,1256],{"class":351},[345,1815,1816],{"class":355},"Move",[345,1818,1819],{"class":359}," { x, y } ",[345,1821,1822],{"class":351},"=>",[345,1824,395],{"class":359},[345,1826,1827,1829,1831,1834],{"class":347,"line":659},[345,1828,1795],{"class":355},[345,1830,440],{"class":359},[345,1832,1833],{"class":443},"\"Move to ({}, {})\"",[345,1835,1836],{"class":359},", x, y);\n",[345,1838,1839],{"class":347,"line":680},[345,1840,1807],{"class":359},[345,1842,1843,1845,1847,1850,1853,1855],{"class":347,"line":696},[345,1844,1780],{"class":355},[345,1846,1256],{"class":351},[345,1848,1849],{"class":355},"Write",[345,1851,1852],{"class":359},"(text) ",[345,1854,1822],{"class":351},[345,1856,395],{"class":359},[345,1858,1859,1861,1863,1866],{"class":347,"line":921},[345,1860,1795],{"class":355},[345,1862,440],{"class":359},[345,1864,1865],{"class":443},"\"Write message: {}\"",[345,1867,1868],{"class":359},", text);\n",[345,1870,1871],{"class":347,"line":926},[345,1872,1807],{"class":359},[345,1874,1875],{"class":347,"line":950},[345,1876,866],{"class":359},[345,1878,1879],{"class":347,"line":1161},[345,1880,472],{"class":359},[22,1882],{"className":1883},[25],[27,1885,1886,1887,1890,1891,1894],{},"In this example, we define an enum called ",[75,1888,1889],{},"Message"," with different variants. The ",[75,1892,1893],{},"match"," keyword allows us to pattern match against each variant and execute the corresponding code block. Pattern matching simplifies the handling of different types of messages and ensures comprehensive coverage.",[22,1896],{"className":1897},[315],[27,1899,1900],{},[330,1901,1902],{},"Example 2: Destructuring Tuples",[22,1904],{"className":1905},[25],[337,1907,1909],{"className":339,"code":1908,"filename":341,"language":249,"meta":231,"style":231},"fn print_coordinates(&(x, y): &(i32, i32)) {\n    println!(\"Coordinates: ({}, {})\", x, y);\n}\n\nfn main() {\n    let coordinates = (10, 20);\n    print_coordinates(&coordinates);\n}\n",[75,1910,1911,1940,1951,1955,1959,1967,1989,2001],{"__ignoreMap":231},[345,1912,1913,1915,1918,1920,1922,1925,1927,1929,1931,1933,1935,1937],{"class":347,"line":348},[345,1914,352],{"class":351},[345,1916,1917],{"class":355}," print_coordinates",[345,1919,440],{"class":359},[345,1921,829],{"class":351},[345,1923,1924],{"class":359},"(x, y)",[345,1926,530],{"class":351},[345,1928,1608],{"class":351},[345,1930,440],{"class":359},[345,1932,570],{"class":355},[345,1934,125],{"class":359},[345,1936,570],{"class":355},[345,1938,1939],{"class":359},")) {\n",[345,1941,1942,1944,1946,1949],{"class":347,"line":232},[345,1943,437],{"class":355},[345,1945,440],{"class":359},[345,1947,1948],{"class":443},"\"Coordinates: ({}, {})\"",[345,1950,1836],{"class":359},[345,1952,1953],{"class":347,"line":385},[345,1954,472],{"class":359},[345,1956,1957],{"class":347,"line":398},[345,1958,606],{"emptyLinePlaceholder":242},[345,1960,1961,1963,1965],{"class":347,"line":416},[345,1962,352],{"class":351},[345,1964,356],{"class":355},[345,1966,360],{"class":359},[345,1968,1969,1971,1974,1976,1979,1982,1984,1987],{"class":347,"line":428},[345,1970,365],{"class":351},[345,1972,1973],{"class":359}," coordinates ",[345,1975,371],{"class":351},[345,1977,1978],{"class":359}," (",[345,1980,1981],{"class":374},"10",[345,1983,125],{"class":359},[345,1985,1986],{"class":374},"20",[345,1988,677],{"class":359},[345,1990,1991,1994,1996,1998],{"class":347,"line":434},[345,1992,1993],{"class":355},"    print_coordinates",[345,1995,440],{"class":359},[345,1997,829],{"class":351},[345,1999,2000],{"class":359},"coordinates);\n",[345,2002,2003],{"class":347,"line":453},[345,2004,472],{"class":359},[22,2006],{"className":2007},[25],[27,2009,2010,2011,2014,2015,2018,2019,2021],{},"Here, we have a function called ",[75,2012,2013],{},"print_coordinates"," that accepts a reference to a tuple ",[75,2016,2017],{},"(i32, i32)"," as a parameter. By using pattern matching, we can easily destructure the tuple into its individual components ",[75,2020,1924],{},". This enables us to access and utilize the coordinates within the function.",[27,2023,2024],{},"Pattern matching allows developers to handle complex scenarios and extract values from data structures in a concise and expressive manner. By embracing pattern matching, Rust programmers can write clean and structured code that effectively handles diverse cases.",[22,2026],{"className":2027},[14],[60,2029,2031],{"id":2030},"_4-lifetimes-in-rust-preventing-dangling-references-and-fixing-errors","4. Lifetimes in Rust: Preventing Dangling References and Fixing Errors",[27,2033,2034],{},"Rust's lifetime system ensures that references are always valid and prevents dangling references, which are references to memory that no longer exists. Lifetimes track the duration in which a reference is valid and enforce strict rules to guarantee memory safety. Understanding lifetimes, avoiding dangling references, and fixing related errors is crucial for writing reliable and efficient code in Rust.",[22,2036],{"className":2037},[14],[27,2039,2040],{},[330,2041,2042],{},"Example 1: Dangling Reference",[22,2044],{"className":2045},[25],[337,2047,2049],{"className":339,"code":2048,"filename":341,"language":249,"meta":231,"style":231},"fn get_string() -> &String {\n    let string = String::from(\"Hello\");\n    &string\n}\n\nfn main() {\n    let dangling_ref = get_string();\n    println!(\"Dangling reference: {}\", dangling_ref);\n    // Error: The `string` in `get_string` is dropped, leaving `dangling_ref`\n    // pointing to invalid memory.\n}\n",[75,2050,2051,2069,2089,2097,2101,2105,2113,2126,2138,2143,2148],{"__ignoreMap":231},[345,2052,2053,2055,2058,2061,2063,2065,2067],{"class":347,"line":348},[345,2054,352],{"class":351},[345,2056,2057],{"class":355}," get_string",[345,2059,2060],{"class":359},"() ",[345,2062,547],{"class":351},[345,2064,1608],{"class":351},[345,2066,1611],{"class":355},[345,2068,395],{"class":359},[345,2070,2071,2073,2075,2077,2079,2081,2083,2085,2087],{"class":347,"line":232},[345,2072,365],{"class":351},[345,2074,1392],{"class":359},[345,2076,371],{"class":351},[345,2078,1397],{"class":355},[345,2080,1256],{"class":351},[345,2082,1402],{"class":355},[345,2084,440],{"class":359},[345,2086,1407],{"class":443},[345,2088,677],{"class":359},[345,2090,2091,2094],{"class":347,"line":385},[345,2092,2093],{"class":351},"    &",[345,2095,2096],{"class":359},"string\n",[345,2098,2099],{"class":347,"line":398},[345,2100,472],{"class":359},[345,2102,2103],{"class":347,"line":416},[345,2104,606],{"emptyLinePlaceholder":242},[345,2106,2107,2109,2111],{"class":347,"line":428},[345,2108,352],{"class":351},[345,2110,356],{"class":355},[345,2112,360],{"class":359},[345,2114,2115,2117,2120,2122,2124],{"class":347,"line":434},[345,2116,365],{"class":351},[345,2118,2119],{"class":359}," dangling_ref ",[345,2121,371],{"class":351},[345,2123,2057],{"class":355},[345,2125,1305],{"class":359},[345,2127,2128,2130,2132,2135],{"class":347,"line":453},[345,2129,437],{"class":355},[345,2131,440],{"class":359},[345,2133,2134],{"class":443},"\"Dangling reference: {}\"",[345,2136,2137],{"class":359},", dangling_ref);\n",[345,2139,2140],{"class":347,"line":469},[345,2141,2142],{"class":381},"    // Error: The `string` in `get_string` is dropped, leaving `dangling_ref`\n",[345,2144,2145],{"class":347,"line":640},[345,2146,2147],{"class":381},"    // pointing to invalid memory.\n",[345,2149,2150],{"class":347,"line":645},[345,2151,472],{"class":359},[22,2153],{"className":2154},[25],[27,2156,704,2157,2160,2161,2163,2164,2166,2167,2170,2171,2174],{},[75,2158,2159],{},"get_string"," function creates a ",[75,2162,1611],{}," and returns a reference to it. However, since the reference's lifetime is tied to the local scope of the ",[75,2165,2159],{}," function, it becomes a dangling reference once the function ends. When the ",[75,2168,2169],{},"dangling_ref"," is used in the ",[75,2172,2173],{},"main"," function, it points to invalid memory, leading to undefined behavior and a potential crash. Rust's lifetime system prevents this scenario by disallowing dangling references at compile time.",[22,2176],{"className":2177},[315],[27,2179,2180],{},[330,2181,2182],{},"Example 2: Proper Lifetime Annotation",[22,2184],{"className":2185},[25],[337,2187,2189],{"className":339,"code":2188,"filename":341,"language":249,"meta":231,"style":231},"fn get_longest\u003C'a>(x: &'a str, y: &'a str) -> &'a str {\n    if x.len() > y.len() {\n        x\n    } else {\n        y\n    }\n}\n\nfn main() {\n    let string1 = String::from(\"Hello\");\n    let result;\n    {\n        let string2 = String::from(\"World\");\n        result = get_longest(&string1, &string2);\n        println!(\"Longest string: {}\", result);\n    }\n    // Both `string1` and `string2` are still valid until this point, so the\n    // reference `result` is not dangling.\n}\n",[75,2190,2191,2244,2265,2270,2280,2285,2289,2293,2297,2305,2326,2333,2338,2360,2381,2393,2397,2402,2407],{"__ignoreMap":231},[345,2192,2193,2195,2198,2201,2203,2206,2208,2210,2213,2215,2218,2220,2222,2224,2226,2228,2230,2232,2234,2236,2238,2240,2242],{"class":347,"line":348},[345,2194,352],{"class":351},[345,2196,2197],{"class":355}," get_longest",[345,2199,2200],{"class":359},"\u003C'",[345,2202,31],{"class":355},[345,2204,2205],{"class":359},">(x",[345,2207,530],{"class":351},[345,2209,1608],{"class":351},[345,2211,2212],{"class":359},"'",[345,2214,31],{"class":355},[345,2216,2217],{"class":355}," str",[345,2219,1724],{"class":359},[345,2221,530],{"class":351},[345,2223,1608],{"class":351},[345,2225,2212],{"class":359},[345,2227,31],{"class":355},[345,2229,2217],{"class":355},[345,2231,544],{"class":359},[345,2233,547],{"class":351},[345,2235,1608],{"class":351},[345,2237,2212],{"class":359},[345,2239,31],{"class":355},[345,2241,2217],{"class":355},[345,2243,395],{"class":359},[345,2245,2246,2249,2252,2254,2256,2259,2261,2263],{"class":347,"line":232},[345,2247,2248],{"class":351},"    if",[345,2250,2251],{"class":359}," x",[345,2253,139],{"class":351},[345,2255,1640],{"class":355},[345,2257,2258],{"class":359},"() > y",[345,2260,139],{"class":351},[345,2262,1640],{"class":355},[345,2264,360],{"class":359},[345,2266,2267],{"class":347,"line":385},[345,2268,2269],{"class":359},"        x\n",[345,2271,2272,2275,2278],{"class":347,"line":398},[345,2273,2274],{"class":359},"    } ",[345,2276,2277],{"class":351},"else",[345,2279,395],{"class":359},[345,2281,2282],{"class":347,"line":416},[345,2283,2284],{"class":359},"        y\n",[345,2286,2287],{"class":347,"line":428},[345,2288,866],{"class":359},[345,2290,2291],{"class":347,"line":434},[345,2292,472],{"class":359},[345,2294,2295],{"class":347,"line":453},[345,2296,606],{"emptyLinePlaceholder":242},[345,2298,2299,2301,2303],{"class":347,"line":469},[345,2300,352],{"class":351},[345,2302,356],{"class":355},[345,2304,360],{"class":359},[345,2306,2307,2309,2312,2314,2316,2318,2320,2322,2324],{"class":347,"line":640},[345,2308,365],{"class":351},[345,2310,2311],{"class":359}," string1 ",[345,2313,371],{"class":351},[345,2315,1397],{"class":355},[345,2317,1256],{"class":351},[345,2319,1402],{"class":355},[345,2321,440],{"class":359},[345,2323,1407],{"class":443},[345,2325,677],{"class":359},[345,2327,2328,2330],{"class":347,"line":645},[345,2329,365],{"class":351},[345,2331,2332],{"class":359}," result;\n",[345,2334,2335],{"class":347,"line":650},[345,2336,2337],{"class":359},"    {\n",[345,2339,2340,2342,2345,2347,2349,2351,2353,2355,2358],{"class":347,"line":659},[345,2341,401],{"class":351},[345,2343,2344],{"class":359}," string2 ",[345,2346,371],{"class":351},[345,2348,1397],{"class":355},[345,2350,1256],{"class":351},[345,2352,1402],{"class":355},[345,2354,440],{"class":359},[345,2356,2357],{"class":443},"\"World\"",[345,2359,677],{"class":359},[345,2361,2362,2365,2367,2369,2371,2373,2376,2378],{"class":347,"line":680},[345,2363,2364],{"class":359},"        result ",[345,2366,371],{"class":351},[345,2368,2197],{"class":355},[345,2370,440],{"class":359},[345,2372,829],{"class":351},[345,2374,2375],{"class":359},"string1, ",[345,2377,829],{"class":351},[345,2379,2380],{"class":359},"string2);\n",[345,2382,2383,2385,2387,2390],{"class":347,"line":696},[345,2384,1094],{"class":355},[345,2386,440],{"class":359},[345,2388,2389],{"class":443},"\"Longest string: {}\"",[345,2391,2392],{"class":359},", result);\n",[345,2394,2395],{"class":347,"line":921},[345,2396,866],{"class":359},[345,2398,2399],{"class":347,"line":926},[345,2400,2401],{"class":381},"    // Both `string1` and `string2` are still valid until this point, so the\n",[345,2403,2404],{"class":347,"line":950},[345,2405,2406],{"class":381},"    // reference `result` is not dangling.\n",[345,2408,2409],{"class":347,"line":1161},[345,2410,472],{"class":359},[22,2412],{"className":2413},[25],[27,2415,2416,2417,2420,2421,2424,2425,966,2427,2430,2431,2433,2434,966,2437,2440,2441,2443,2444,2447],{},"In this updated example, the ",[75,2418,2419],{},"get_longest"," function has a lifetime annotation ",[75,2422,2423],{},"'a"," that indicates the references ",[75,2426,481],{},[75,2428,2429],{},"y"," have the same lifetime. The main function creates two ",[75,2432,1611],{}," instances, ",[75,2435,2436],{},"string1",[75,2438,2439],{},"string2",", and passes their references to ",[75,2442,2419],{},". Since the lifetime of the references is properly managed, the returned reference ",[75,2445,2446],{},"result"," remains valid and does not become a dangling reference.",[22,2449],{"className":2450},[315],[27,2452,2453],{},[330,2454,2455],{},"Example 3: Fixing the Dangling Reference Error",[22,2457],{"className":2458},[25],[337,2460,2462],{"className":339,"code":2461,"filename":341,"language":249,"meta":231,"style":231},"fn get_string() -> String {\n    let string = String::from(\"Hello\");\n    string\n}\n\nfn main() {\n    let valid_string = get_string();\n    let valid_ref = &valid_string;\n    println!(\"Valid reference: {}\", valid_ref);\n    // The `valid_string` is still valid, and the reference `valid_ref` can be\n    // safely used.\n}\n",[75,2463,2464,2478,2498,2503,2507,2511,2519,2532,2546,2558,2563,2568],{"__ignoreMap":231},[345,2465,2466,2468,2470,2472,2474,2476],{"class":347,"line":348},[345,2467,352],{"class":351},[345,2469,2057],{"class":355},[345,2471,2060],{"class":359},[345,2473,547],{"class":351},[345,2475,1397],{"class":355},[345,2477,395],{"class":359},[345,2479,2480,2482,2484,2486,2488,2490,2492,2494,2496],{"class":347,"line":232},[345,2481,365],{"class":351},[345,2483,1392],{"class":359},[345,2485,371],{"class":351},[345,2487,1397],{"class":355},[345,2489,1256],{"class":351},[345,2491,1402],{"class":355},[345,2493,440],{"class":359},[345,2495,1407],{"class":443},[345,2497,677],{"class":359},[345,2499,2500],{"class":347,"line":385},[345,2501,2502],{"class":359},"    string\n",[345,2504,2505],{"class":347,"line":398},[345,2506,472],{"class":359},[345,2508,2509],{"class":347,"line":416},[345,2510,606],{"emptyLinePlaceholder":242},[345,2512,2513,2515,2517],{"class":347,"line":428},[345,2514,352],{"class":351},[345,2516,356],{"class":355},[345,2518,360],{"class":359},[345,2520,2521,2523,2526,2528,2530],{"class":347,"line":434},[345,2522,365],{"class":351},[345,2524,2525],{"class":359}," valid_string ",[345,2527,371],{"class":351},[345,2529,2057],{"class":355},[345,2531,1305],{"class":359},[345,2533,2534,2536,2539,2541,2543],{"class":347,"line":453},[345,2535,365],{"class":351},[345,2537,2538],{"class":359}," valid_ref ",[345,2540,371],{"class":351},[345,2542,1608],{"class":351},[345,2544,2545],{"class":359},"valid_string;\n",[345,2547,2548,2550,2552,2555],{"class":347,"line":469},[345,2549,437],{"class":355},[345,2551,440],{"class":359},[345,2553,2554],{"class":443},"\"Valid reference: {}\"",[345,2556,2557],{"class":359},", valid_ref);\n",[345,2559,2560],{"class":347,"line":640},[345,2561,2562],{"class":381},"    // The `valid_string` is still valid, and the reference `valid_ref` can be\n",[345,2564,2565],{"class":347,"line":645},[345,2566,2567],{"class":381},"    // safely used.\n",[345,2569,2570],{"class":347,"line":650},[345,2571,472],{"class":359},[22,2573],{"className":2574},[25],[27,2576,2577,2578,2580,2581,2583,2584,2586,2587,2589,2590,2592,2593,2596,2597,2600],{},"In this example, we modify the ",[75,2579,2159],{}," function to return the actual ",[75,2582,1611],{}," instead of a reference to it. By doing so, the ownership of the ",[75,2585,1611],{}," is transferred to the caller, ensuring that the string remains valid outside the function scope. In the ",[75,2588,2173],{}," function, we assign the returned ",[75,2591,1611],{}," to the ",[75,2594,2595],{},"valid_string"," variable and create a valid reference, ",[75,2598,2599],{},"valid_ref",", to it. This approach avoids the issue of dangling references altogether, as the data remains accessible and valid throughout its lifetime.",[27,2602,2603],{},"By returning the actual owned value rather than a reference in situations where it makes sense, developers can avoid dangling references and leverage Rust's ownership model to ensure memory safety. It's important to consider the lifetime requirements and choose the appropriate approach based on the specific use case.",[22,2605],{"className":2606},[14],[60,2608,2610],{"id":2609},"_5-single-mutable-reference-ensuring-mutability-and-memory-safety","5. Single Mutable Reference: Ensuring Mutability and Memory Safety",[27,2612,2613],{},"In Rust, the concept of ownership extends to mutable references, ensuring that there is only a single mutable reference to a variable within a particular scope. This design choice enforces strict rules to prevent data races and guarantee memory safety, making Rust code highly reliable. Understanding why Rust allows only one mutable reference and how it enhances the safety and predictability of your programs is essential.",[27,2615,2616],{},"The restriction of having a single mutable reference to a variable prevents potential issues such as data races, where multiple threads concurrently access and modify the same data, leading to unpredictable and erroneous behavior. By allowing only one mutable reference, Rust avoids scenarios where multiple references could simultaneously modify a value and cause race conditions.",[22,2618],{"className":2619},[14],[27,2621,2622],{},[330,2623,2624],{},"Example 1: Single Mutable Reference in Action",[22,2626],{"className":2627},[25],[337,2629,2631],{"className":339,"code":2630,"filename":341,"language":249,"meta":231,"style":231},"fn main() {\n    let mut number = 5;\n    let reference = &mut number; // Mutable reference\n    *reference += 1; // Modifying the value through the reference\n    println!(\"Modified number: {}\", number); // Output: Modified number: 6\n}\n",[75,2632,2633,2641,2657,2675,2694,2709],{"__ignoreMap":231},[345,2634,2635,2637,2639],{"class":347,"line":348},[345,2636,352],{"class":351},[345,2638,356],{"class":355},[345,2640,360],{"class":359},[345,2642,2643,2645,2648,2651,2653,2655],{"class":347,"line":232},[345,2644,365],{"class":351},[345,2646,2647],{"class":351}," mut",[345,2649,2650],{"class":359}," number ",[345,2652,371],{"class":351},[345,2654,375],{"class":374},[345,2656,1048],{"class":359},[345,2658,2659,2661,2664,2666,2669,2672],{"class":347,"line":385},[345,2660,365],{"class":351},[345,2662,2663],{"class":359}," reference ",[345,2665,371],{"class":351},[345,2667,2668],{"class":351}," &mut",[345,2670,2671],{"class":359}," number; ",[345,2673,2674],{"class":381},"// Mutable reference\n",[345,2676,2677,2680,2683,2686,2689,2691],{"class":347,"line":398},[345,2678,2679],{"class":351},"    *",[345,2681,2682],{"class":359},"reference ",[345,2684,2685],{"class":351},"+=",[345,2687,2688],{"class":374}," 1",[345,2690,378],{"class":359},[345,2692,2693],{"class":381},"// Modifying the value through the reference\n",[345,2695,2696,2698,2700,2703,2706],{"class":347,"line":416},[345,2697,437],{"class":355},[345,2699,440],{"class":359},[345,2701,2702],{"class":443},"\"Modified number: {}\"",[345,2704,2705],{"class":359},", number); ",[345,2707,2708],{"class":381},"// Output: Modified number: 6\n",[345,2710,2711],{"class":347,"line":428},[345,2712,472],{"class":359},[22,2714],{"className":2715},[25],[27,2717,2718,2719,2722,2723,2726,2727,2730,2731,2734,2735,2737,2738,2740,2741,2743],{},"In this example, we define a mutable variable ",[75,2720,2721],{},"number"," and then create a mutable reference ",[75,2724,2725],{},"reference"," to it using the ",[75,2728,2729],{},"&mut"," syntax. By dereferencing the reference with ",[75,2732,2733],{},"*reference",", we can modify the value of ",[75,2736,2721],{},". In this case, we increment ",[75,2739,2721],{}," by 1. As a result, the value of ",[75,2742,2721],{}," is changed to 6, and we can observe the modified value when we print it.",[27,2745,2746],{},"By allowing only one mutable reference to a variable, Rust ensures that modifications are well-controlled, preventing potential conflicts and race conditions. This restriction guarantees that concurrent access to mutable data is properly synchronized, making Rust programs inherently thread-safe and avoiding subtle bugs caused by data races.",[27,2748,2749],{},"While the limitation of a single mutable reference might require some adjustments in how you structure your code, it contributes to the overall safety and reliability of your Rust programs. It encourages explicit and intentional control over mutable access, reducing the chances of programming errors and making it easier to reason about code behavior.",[27,2751,2752,2753,125,2756,135,2759,2762],{},"In situations where you need to modify data from different parts of your code simultaneously, Rust provides mechanisms like interior mutability, which allows for controlled mutability through specific types such as ",[75,2754,2755],{},"Cell",[75,2757,2758],{},"RefCell",[75,2760,2761],{},"Mutex",". These constructs ensure that mutations are synchronized and safe, even in multi-threaded scenarios.",[22,2764],{"className":2765},[14],[60,2767,2769],{"id":2768},"_6-simultaneous-access-with-synchronization-primitives","6. Simultaneous Access with Synchronization Primitives",[27,2771,2772],{},"While Rust's ownership and borrowing model restricts simultaneous mutable access to a variable, there are cases where you genuinely need multiple references for concurrent read or write operations. Rust provides synchronization primitives that allow controlled and safe simultaneous access to shared data, ensuring thread safety and preventing data races. Let's explore one such synchronization primitive, the mutex, and how it enables concurrent access without compromising safety.",[22,2774],{"className":2775},[315],[305,2777,2779],{"id":2778},"mutex-synchronizing-exclusive-access","Mutex: Synchronizing Exclusive Access",[27,2781,2782],{},"One of the most commonly used synchronization primitives in Rust is the mutex (short for mutual exclusion). A mutex allows multiple threads to access a shared resource, but only one thread can have exclusive access to it at a time. Other threads must wait until the owning thread releases the lock.",[27,2784,2785],{},[330,2786,2787],{},"Example: Simultaneous Access with Mutex",[22,2789],{"className":2790},[25],[337,2792,2794],{"className":339,"code":2793,"filename":341,"language":249,"meta":231,"style":231},"use std::sync::{Mutex, Arc};\nuse std::thread;\n\nfn main() {\n    let counter = Arc::new(Mutex::new(0));\n    let mut handles = vec![];\n\n    for _ in 0..10 {\n        let counter = Arc::clone(&counter);\n        let handle = thread::spawn(move || {\n            let mut data = counter.lock().unwrap();\n            *data += 1;\n        });\n        handles.push(handle);\n    }\n\n    for handle in handles {\n        handle.join().expect(\"Thread panicked\");\n    }\n\n    println!(\"Counter value: {:?}\", *counter.lock().unwrap());\n}\n",[75,2795,2796,2824,2835,2839,2847,2879,2895,2899,2918,2940,2967,2997,3011,3016,3029,3033,3037,3048,3072,3076,3080,3109],{"__ignoreMap":231},[345,2797,2798,2801,2804,2806,2809,2811,2814,2816,2818,2821],{"class":347,"line":348},[345,2799,2800],{"class":351},"use",[345,2802,2803],{"class":355}," std",[345,2805,1256],{"class":351},[345,2807,2808],{"class":355},"sync",[345,2810,1256],{"class":351},[345,2812,2813],{"class":359},"{",[345,2815,2761],{"class":355},[345,2817,125],{"class":359},[345,2819,2820],{"class":355},"Arc",[345,2822,2823],{"class":359},"};\n",[345,2825,2826,2828,2830,2832],{"class":347,"line":232},[345,2827,2800],{"class":351},[345,2829,2803],{"class":355},[345,2831,1256],{"class":351},[345,2833,2834],{"class":359},"thread;\n",[345,2836,2837],{"class":347,"line":385},[345,2838,606],{"emptyLinePlaceholder":242},[345,2840,2841,2843,2845],{"class":347,"line":398},[345,2842,352],{"class":351},[345,2844,356],{"class":355},[345,2846,360],{"class":359},[345,2848,2849,2851,2854,2856,2859,2861,2863,2865,2867,2869,2871,2873,2876],{"class":347,"line":416},[345,2850,365],{"class":351},[345,2852,2853],{"class":359}," counter ",[345,2855,371],{"class":351},[345,2857,2858],{"class":355}," Arc",[345,2860,1256],{"class":351},[345,2862,1259],{"class":355},[345,2864,440],{"class":359},[345,2866,2761],{"class":355},[345,2868,1256],{"class":351},[345,2870,1259],{"class":355},[345,2872,440],{"class":359},[345,2874,2875],{"class":374},"0",[345,2877,2878],{"class":359},"));\n",[345,2880,2881,2883,2885,2888,2890,2892],{"class":347,"line":428},[345,2882,365],{"class":351},[345,2884,2647],{"class":351},[345,2886,2887],{"class":359}," handles ",[345,2889,371],{"class":351},[345,2891,1248],{"class":355},[345,2893,2894],{"class":359},"[];\n",[345,2896,2897],{"class":347,"line":434},[345,2898,606],{"emptyLinePlaceholder":242},[345,2900,2901,2903,2906,2908,2911,2914,2916],{"class":347,"line":453},[345,2902,1282],{"class":351},[345,2904,2905],{"class":359}," _ ",[345,2907,1288],{"class":351},[345,2909,2910],{"class":374}," 0",[345,2912,2913],{"class":351},"..",[345,2915,1981],{"class":374},[345,2917,395],{"class":359},[345,2919,2920,2922,2924,2926,2928,2930,2933,2935,2937],{"class":347,"line":469},[345,2921,401],{"class":351},[345,2923,2853],{"class":359},[345,2925,371],{"class":351},[345,2927,2858],{"class":355},[345,2929,1256],{"class":351},[345,2931,2932],{"class":355},"clone",[345,2934,440],{"class":359},[345,2936,829],{"class":351},[345,2938,2939],{"class":359},"counter);\n",[345,2941,2942,2944,2947,2949,2952,2954,2957,2959,2962,2965],{"class":347,"line":640},[345,2943,401],{"class":351},[345,2945,2946],{"class":359}," handle ",[345,2948,371],{"class":351},[345,2950,2951],{"class":355}," thread",[345,2953,1256],{"class":351},[345,2955,2956],{"class":355},"spawn",[345,2958,440],{"class":359},[345,2960,2961],{"class":351},"move",[345,2963,2964],{"class":351}," ||",[345,2966,395],{"class":359},[345,2968,2969,2972,2974,2977,2979,2982,2984,2987,2990,2992,2995],{"class":347,"line":645},[345,2970,2971],{"class":351},"            let",[345,2973,2647],{"class":351},[345,2975,2976],{"class":359}," data ",[345,2978,371],{"class":351},[345,2980,2981],{"class":359}," counter",[345,2983,139],{"class":351},[345,2985,2986],{"class":355},"lock",[345,2988,2989],{"class":359},"()",[345,2991,139],{"class":351},[345,2993,2994],{"class":355},"unwrap",[345,2996,1305],{"class":359},[345,2998,2999,3002,3005,3007,3009],{"class":347,"line":650},[345,3000,3001],{"class":351},"            *",[345,3003,3004],{"class":359},"data ",[345,3006,2685],{"class":351},[345,3008,2688],{"class":374},[345,3010,1048],{"class":359},[345,3012,3013],{"class":347,"line":659},[345,3014,3015],{"class":359},"        });\n",[345,3017,3018,3021,3023,3026],{"class":347,"line":680},[345,3019,3020],{"class":359},"        handles",[345,3022,139],{"class":351},[345,3024,3025],{"class":355},"push",[345,3027,3028],{"class":359},"(handle);\n",[345,3030,3031],{"class":347,"line":696},[345,3032,866],{"class":359},[345,3034,3035],{"class":347,"line":921},[345,3036,606],{"emptyLinePlaceholder":242},[345,3038,3039,3041,3043,3045],{"class":347,"line":926},[345,3040,1282],{"class":351},[345,3042,2946],{"class":359},[345,3044,1288],{"class":351},[345,3046,3047],{"class":359}," handles {\n",[345,3049,3050,3053,3055,3058,3060,3062,3065,3067,3070],{"class":347,"line":950},[345,3051,3052],{"class":359},"        handle",[345,3054,139],{"class":351},[345,3056,3057],{"class":355},"join",[345,3059,2989],{"class":359},[345,3061,139],{"class":351},[345,3063,3064],{"class":355},"expect",[345,3066,440],{"class":359},[345,3068,3069],{"class":443},"\"Thread panicked\"",[345,3071,677],{"class":359},[345,3073,3074],{"class":347,"line":1161},[345,3075,866],{"class":359},[345,3077,3078],{"class":347,"line":1166},[345,3079,606],{"emptyLinePlaceholder":242},[345,3081,3082,3084,3086,3089,3091,3093,3096,3098,3100,3102,3104,3106],{"class":347,"line":1175},[345,3083,437],{"class":355},[345,3085,440],{"class":359},[345,3087,3088],{"class":443},"\"Counter value: {:?}\"",[345,3090,125],{"class":359},[345,3092,853],{"class":351},[345,3094,3095],{"class":359},"counter",[345,3097,139],{"class":351},[345,3099,2986],{"class":355},[345,3101,2989],{"class":359},[345,3103,139],{"class":351},[345,3105,2994],{"class":355},[345,3107,3108],{"class":359},"());\n",[345,3110,3111],{"class":347,"line":1194},[345,3112,472],{"class":359},[22,3114],{"className":3115},[25],[27,3117,3118,3119,3121,3122,3124,3125,3127],{},"In this example, we use an additional synchronization primitive, ",[75,3120,2820],{}," (short for atomic reference counting), to share ownership of the mutex ",[75,3123,3095],{}," among multiple threads. ",[75,3126,2820],{}," enables multiple ownership of a value across threads, ensuring its reference count is properly tracked.",[27,3129,3130,3131,3133,3134,3137,3138,3140,3141,3143,3144,3147],{},"We create an ",[75,3132,2820],{}," around the mutex ",[75,3135,3136],{},"Mutex::new(0)",", which initializes the shared counter to zero. Each thread receives a cloned ",[75,3139,2820],{}," reference to the counter, incrementing it by acquiring a lock on the mutex using the ",[75,3142,2986],{}," method. Once the increment is complete, the lock is automatically released as the ",[75,3145,3146],{},"data"," variable goes out of scope.",[27,3149,3150,3151,3153],{},"By using ",[75,3152,2820],{}," to share ownership of the mutex, we ensure that each thread can safely access and modify the counter concurrently. The mutex enforces exclusive access, preventing data races and guaranteeing consistent results.",[27,3155,3156,3157,3159],{},"Using synchronization primitives like mutexes and smart pointers like ",[75,3158,2820],{}," enables Rust programmers to handle cases where simultaneous access to shared data is necessary while ensuring thread safety and preventing data races. By combining these primitives with Rust's ownership and borrowing model, you can build concurrent applications that are both safe and efficient.",[22,3161],{"className":3162},[14],[60,3164,3166],{"id":3165},"conclusion","Conclusion",[27,3168,3169],{},"In summary, Rust is a programming language that offers a unique set of features and concepts to developers. Its ownership and borrowing system ensures memory safety and eliminates common bugs, while pattern matching provides a concise way to handle complex data structures. Lifetimes enforce reference management and prevent dangling references.",[27,3171,3172],{},"Rust's synchronization primitives enable safe concurrent access to shared data, and its support for functional programming and object-oriented programming allows for expressive and modular code. Immutability by default, higher-order functions, structs, methods, traits, and polymorphism contribute to Rust's versatility.",[27,3174,3175],{},"By mastering these core features, developers can write robust, efficient, and safe code in Rust. The language's growing ecosystem and active community make it an exciting choice for a wide range of applications. Embrace Rust's philosophy of safe systems programming and unlock the potential of this powerful language.",[22,3177],{"className":3178},[14],[3180,3181],"hr",{},[22,3183],{"className":3184},[14],[27,3186,3187],{},[3188,3189,3190,3191,3196],"em",{},"Originally published on ",[31,3192,3195],{"href":3193,"rel":3194},"https://medium.com/@dev.davexoyinbo/embracing-perfection-a-journey-into-rust-programming-a524de4f053f",[35],"Medium"," on June 20, 2023.",[3198,3199,3200],"style",{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":231,"searchDepth":232,"depth":232,"links":3202},[3203,3204,3208,3209,3210,3211,3212,3215],{"id":286,"depth":232,"text":287},{"id":296,"depth":232,"text":297,"children":3205},[3206,3207],{"id":307,"depth":385,"text":308},{"id":736,"depth":385,"text":737},{"id":1354,"depth":232,"text":1355},{"id":1672,"depth":232,"text":1673},{"id":2030,"depth":232,"text":2031},{"id":2609,"depth":232,"text":2610},{"id":2768,"depth":232,"text":2769,"children":3213},[3214],{"id":2778,"depth":385,"text":2779},{"id":3165,"depth":232,"text":3166},"2023-06-20T00:00:00.000Z","Exploring Rust's core features and concepts that make it a powerful and compelling language for developers seeking memory safety and performance.",null,{},"/engineering-logs/embracing-perfection-rust","11 min read",{"title":259,"description":3217},"engineering-logs/embracing-perfection-rust",[249,3225,3226,3227,3228],"programming","backend","systems","memory-safety","TDr9G3tuf0NroZecA6wQedb3zhg_jnp3eLqPECXwDRU",{"id":3231,"title":3232,"author":6,"body":3233,"date":3508,"description":3509,"extension":240,"image_url":3218,"meta":3510,"navigation":242,"original_url":3496,"path":3511,"readTime":3512,"seo":3513,"stem":3514,"tags":3515,"__hash__":3523},"engineeringLogs/engineering-logs/programming-soft-skills.md","Is Programming Enough? The Tales of a Software Engineer",{"type":8,"value":3234,"toc":3499},[3235,3239,3242,3245,3248,3251,3254,3256,3259,3262,3265,3268,3271,3274,3278,3281,3284,3290,3293,3296,3299,3302,3305,3309,3312,3315,3318,3321,3324,3327,3330,3333,3336,3339,3342,3345,3349,3352,3355,3358,3361,3364,3367,3370,3373,3394,3397,3402,3405,3409,3412,3415,3420,3423,3426,3429,3433,3436,3439,3442,3445,3450,3456,3462,3468,3471,3473,3476,3479,3482,3485,3487,3490],[11,3236],{"className":3237,"date":3238},[265],"2024-04-28",[17,3240,3232],{"id":3241},"is-programming-enough-the-tales-of-a-software-engineer",[27,3243,3244],{},"Exploring the essential soft skills beyond programming that software engineers need to succeed in the business world",[22,3246],{"className":3247},[276],[278,3249],{":tags":3250},"[\"Software Engineering\", \"Career Development\", \"Soft Skills\", \"Communication\", \"Collaboration\", \"Problem Solving\", \"Business\"]",[22,3252],{"className":3253},[14],[60,3255,287],{"id":286},[27,3257,3258],{},"When the topic of software engineering is discussed, it is often around hard skills like programming, design, DevOps and what not. A key aspect of software engineering — at the risk of offending the hobbyists — is the aspect of making money. Money is (usually) the driving force of a product and it becomes an issue very fast given that most software are business driven.",[22,3260],{"className":3261},[25],[27,3263,3264],{},"Many companies have drowned not because of the fact that they don't have experienced engineers but the fact that other aspects like management, communication, and most importantly, flexibility were not adequately developed. As an example, \"The Peer\", a Nigerian startup which raised about $2.1 million announced they would be shutting down and returning $350 thousand to investors. One of the reasons they said they are shutting down is because they couldn't find a good \"product-market fit.\"",[22,3266],{"className":3267},[25],[27,3269,3270],{},"In as much as it is hard to make a good product, and the fact that the success rate of businesses even for business owners with experience is about 30%, it becomes more and more glaring that hard skills in software engineering, even though very important, are not enough in the business world.",[22,3272],{"className":3273},[14],[60,3275,3277],{"id":3276},"so-what-matters","So What Matters?",[27,3279,3280],{},"In \"The Lean Startup,\" Eric Ries emphasizes the importance of communication and incremental growth throughout the book, but a particularly relevant reference can be found in Chapter 3, \"Experiment.\" Here's a passage that highlights these principles:",[22,3282],{"className":3283},[25],[3285,3286,3287],"blockquote",{},[27,3288,3289],{},"\"Entrepreneurs are more like artists, who must interpret incomplete and conflicting information, than traditional managers, who largely preside over well-defined problems. Instead of making complex five-year plans, we need to create a framework for learning and experimentation.\"",[22,3291],{"className":3292},[25],[27,3294,3295],{},"This passage explains the necessity of constant communication and feedback loops with customers, as well as the value of incremental growth through iterative experimentation rather than relying on rigid long-term plans.",[22,3297],{"className":3298},[25],[27,3300,3301],{},"And this brings us to the first soft skill a software engineer can use to improve himself and increase his relevance — communication.",[22,3303],{"className":3304},[14],[60,3306,3308],{"id":3307},"_1-communication","1. Communication",[27,3310,3311],{},"As a software engineer, I once encountered a situation where active listening proved invaluable. We were developing a new feature for a product, and a client called in, frustrated and confused about how the new interface worked. Instead of jumping to explain or defend the design, I took a step back and listened patiently.",[22,3313],{"className":3314},[25],[27,3316,3317],{},"The client vented about how the new layout made it difficult to find specific functionalities they used frequently. As they spoke, I made note of the features they mentioned and the confusions they expressed with the current workflow.",[22,3319],{"className":3320},[25],[27,3322,3323],{},"Through active listening, I discovered that the core issue wasn't necessarily the design itself, but a lack of clarity in the user flow. The client's frustration stemmed from a disconnect between their mental model and the way the new interface presented information.",[22,3325],{"className":3326},[25],[27,3328,3329],{},"With this understanding, I could approach the situation collaboratively. I explained the reasoning behind the design choices and then worked with the client to identify potential improvements that addressed their concerns. We explored ways to streamline the workflow and make the necessary features more easily discoverable.",[22,3331],{"className":3332},[25],[27,3334,3335],{},"By taking the time to listen and understand the client's perspective, we were able to bridge the gap and find a solution that improved the user experience for everyone. This experience solidified the importance of active listening in the software development process. It allows us to gather valuable user feedback, identify potential issues early on, and ultimately create a product that meets the needs of our users.",[22,3337],{"className":3338},[25],[27,3340,3341],{},"This experience gave me a new perspective, because the struggle wasn't only with being open to get criticism on features that we've been working on for months but also convincing the team that it was important to adjust our workflows. And this was beneficial to the business as it became a portal through which several improvement was done on the feature.",[22,3343],{"className":3344},[14],[60,3346,3348],{"id":3347},"_2-learning-to-be-structured-time-management","2. Learning to be Structured (Time Management)",[27,3350,3351],{},"If you're one to find complete satisfaction from your work alone, you can skip this section to the next... If you're still here I'm guessing you feel like you need some touch of polygamy (not as related to a sexual relation) to keep yourself happy. As an adult, life is definitely not just about work, and it is way too easy to get lost in it.",[22,3353],{"className":3354},[25],[27,3356,3357],{},"This can cause you not to spend enough time with your wife, your friends or do the dumb things you like to do whether it be going to costume parties or playing an instrument. Life is filled with so many dumb things that makes us happy, but we tend not to be able to walk between the lines.",[22,3359],{"className":3360},[25],[27,3362,3363],{},"There are generally three kinds of people in this regard — (1) those who work too much; (2) those who work enough and; (3) those who work too little.",[22,3365],{"className":3366},[25],[27,3368,3369],{},"With the advent of remote working, it is quite easy to jump between these three demographic and it is important to structure your work and other work activities else you might not enjoy life to the fullest. The following are tips to create a structure keep you optimal:",[22,3371],{"className":3372},[25],[3374,3375,3376,3383,3389],"ol",{},[3377,3378,3379,3382],"li",{},[330,3380,3381],{},"Let work time be work time"," - If you work 9 to 5, work between those hours and drop your computer after then (you have to make rooms for exceptions though)",[3377,3384,3385,3388],{},[330,3386,3387],{},"Don't take your work to your personal life"," - Go on dates with your girlfriend and spend time with the kids.",[3377,3390,3391],{},[330,3392,3393],{},"Plan the tasks for the next day the day before",[22,3395],{"className":3396},[25],[3285,3398,3399],{},[27,3400,3401],{},"When you have some sort of structure in your personal life, however minor, that is when you can take this to your professional life and make a difference.",[22,3403],{"className":3404},[14],[60,3406,3408],{"id":3407},"_3-collaboration","3. Collaboration",[27,3410,3411],{},"In as much as there are products one can build alone, large-scale products usually require a team of individuals with their roles clearly stated — even if there would be overlaps. Let me not bore you with long talk, but the simple thing is a larger project/product would need more people and to be relevant, asides from being a good software engineer (skill wise), you cannot run away from the fact that you would need to work with others.",[22,3413],{"className":3414},[25],[3285,3416,3417],{},[27,3418,3419],{},"Alice, a whiz at code, struggled with user interfaces. Ben, a design guru, couldn't write a line of code. Together, they created an app that revolutionized the industry.",[22,3421],{"className":3422},[25],[27,3424,3425],{},"Take this with a grain of salt.",[22,3427],{"className":3428},[14],[60,3430,3432],{"id":3431},"_4-problem-solving","4. Problem Solving",[27,3434,3435],{},"Software engineering is all about problem solving. A good analogy would be your thought and your speech. Your speech is just an audible articulation of your thoughts. This is the same way coding is a syntactic articulation of a solution you have developed for a problem.",[22,3437],{"className":3438},[25],[27,3440,3441],{},"You can develop problem solving skills by:",[22,3443],{"className":3444},[25],[27,3446,3447],{},[330,3448,3449],{},"a. Practicing with coding challenges",[27,3451,3452,3455],{},[330,3453,3454],{},"b. Working on open-source projects"," - Contributing to open-source projects exposes you to real-world codebases and challenges also if I'm being honest. The good thing about working on open-source is that you definitely have to think about how others are using your solutions and you would let a great bunch from how others approach problems also.",[27,3457,3458,3461],{},[330,3459,3460],{},"c. Break down complex problems"," - Usually, a big problem is a combination of smaller ones. Knowing how to efficiently break problem into smaller pieces, solving those and artfully joining them together would be a sharp katana under your belt.",[27,3463,3464,3467],{},[330,3465,3466],{},"d. Learn from mistakes"," - When we finally stumble on a solution for an unfamiliar problem (eg. a coding problem), it is very common to have gone through several inefficient ones, when you finally get the optimal solution, don't be scared to delete the whole solution and re-write it.",[22,3469],{"className":3470},[14],[60,3472,3166],{"id":3165},[27,3474,3475],{},"In conclusion, while strong coding skills are a valuable foundation, becoming a well-rounded software engineer requires a broader skillset. This includes soft skills like communication, time management, and collaboration to effectively bridge the gap between technical expertise and real-world needs.",[22,3477],{"className":3478},[25],[27,3480,3481],{},"By honing these complementary abilities, software engineers can not only create innovative products but also ensure they are user-friendly, solve genuine problems, and contribute to a successful business model. Remember, software engineering is a team effort, and effective communication and collaboration are essential for turning your problem-solving skills into successful products.",[22,3483],{"className":3484},[14],[3180,3486],{},[22,3488],{"className":3489},[14],[27,3491,3492],{},[3188,3493,3190,3494,3498],{},[31,3495,3195],{"href":3496,"rel":3497},"https://medium.com/@dev.davexoyinbo/is-programming-enough-the-tales-of-a-software-engineer-d697057dfd5e",[35]," by David Oyinbo",{"title":231,"searchDepth":232,"depth":232,"links":3500},[3501,3502,3503,3504,3505,3506,3507],{"id":286,"depth":232,"text":287},{"id":3276,"depth":232,"text":3277},{"id":3307,"depth":232,"text":3308},{"id":3347,"depth":232,"text":3348},{"id":3407,"depth":232,"text":3408},{"id":3431,"depth":232,"text":3432},{"id":3165,"depth":232,"text":3166},"2024-04-28T00:00:00.000Z","Exploring the essential soft skills beyond programming that software engineers need to succeed in the business world - from communication and time management to collaboration and problem-solving",{},"/engineering-logs/programming-soft-skills","7 min",{"title":3232,"description":3509},"engineering-logs/programming-soft-skills",[3516,3517,3518,3519,3520,3521,3522],"software-engineering","career-development","soft-skills","communication","collaboration","problem-solving","business","AI5cg1IgQNpLnYy7TK27PKTf2Qp-phBLtbR6wlACfko",{"id":3525,"title":3526,"author":6,"body":3527,"date":5395,"description":5396,"extension":240,"image_url":3218,"meta":5397,"navigation":242,"original_url":5376,"path":5398,"readTime":5399,"seo":5400,"stem":5401,"tags":5402,"__hash__":5406},"engineeringLogs/engineering-logs/error-handling-rust.md","Error Handling in Rust Where Bugs Go to Take a Vacation",{"type":8,"value":3528,"toc":5381},[3529,3533,3537,3540,3543,3546,3549,3551,3554,3557,3560,3564,3568,3592,3595,3646,3649,3658,3661,3664,3667,3855,3858,3887,3896,3899,3903,3912,3915,3955,3958,3976,3979,3985,4006,4011,4014,4271,4274,4297,4309,4312,4315,4319,4337,4348,4351,4355,4358,4593,4596,4626,4629,4633,4650,4653,4813,4816,4844,4860,4877,4892,4895,4898,4902,4909,4912,5212,5215,5226,5229,5232,5236,5246,5249,5327,5330,5337,5340,5343,5345,5359,5362,5365,5367,5370,5378],[11,3530],{"className":3531,"date":3532},[265],"2024-02-02",[17,3534,3536],{"id":3535},"error-handling-in-rust-where-bugs-go-to-take-a-vacation","Error Handling in Rust: Where Bugs Go to Take a Vacation!",[27,3538,3539],{},"Safeguarding Software Reliability with Rust's Error Handling Mechanisms",[22,3541],{"className":3542},[276],[278,3544],{":tags":3545},"[\"Rust\", \"Error Handling\", \"Programming\", \"Software Development\", \"Result\", \"Option\"]",[22,3547],{"className":3548},[14],[60,3550,287],{"id":286},[27,3552,3553],{},"Error handling is an essential aspect of software development, ensuring that programs can gracefully handle unexpected situations and recover from errors. Rust, a systems programming language known for its focus on safety and performance, provides robust mechanisms for error handling. In this article, we will explore the various error-handling techniques available in Rust and how they contribute to writing reliable and maintainable code.",[22,3555],{"className":3556},[14],[22,3558],{"className":3559},[14],[60,3561,3563],{"id":3562},"the-result-and-option-enums","The Result and Option Enums",[305,3565,3567],{"id":3566},"result-type","Result Type",[27,3569,3570,3571,966,3574,3577,3578,3580,3581,3584,3585,3588,3589,3591],{},"Rust embraces the use of two special enums, ",[75,3572,3573],{},"Result",[75,3575,3576],{},"Option",", to handle errors and optional values, respectively. The ",[75,3579,3573],{}," enum has two variants: ",[75,3582,3583],{},"Ok(T)",", representing a successful result, and ",[75,3586,3587],{},"Err(E)",", representing an error. By returning a ",[75,3590,3573],{}," from a function, developers can explicitly handle possible errors instead of relying on exceptions or error codes.",[22,3593],{"className":3594},[25],[337,3596,3598],{"className":339,"code":3597,"filename":341,"language":249,"meta":231,"style":231},"enum Result\u003CT, E> {\n    Ok(T),\n    Err(E),\n}\n",[75,3599,3600,3620,3631,3642],{"__ignoreMap":231},[345,3601,3602,3604,3607,3609,3612,3614,3617],{"class":347,"line":348},[345,3603,1697],{"class":351},[345,3605,3606],{"class":355}," Result",[345,3608,521],{"class":359},[345,3610,3611],{"class":355},"T",[345,3613,125],{"class":359},[345,3615,3616],{"class":355},"E",[345,3618,3619],{"class":359},"> {\n",[345,3621,3622,3625,3627,3629],{"class":347,"line":232},[345,3623,3624],{"class":355},"    Ok",[345,3626,440],{"class":359},[345,3628,3611],{"class":355},[345,3630,1743],{"class":359},[345,3632,3633,3636,3638,3640],{"class":347,"line":385},[345,3634,3635],{"class":355},"    Err",[345,3637,440],{"class":359},[345,3639,3616],{"class":355},[345,3641,1743],{"class":359},[345,3643,3644],{"class":347,"line":398},[345,3645,472],{"class":359},[22,3647],{"className":3648},[25],[27,3650,3651,3652,3654,3655,3657],{},"Here, ",[75,3653,3611],{}," represents the type of the value produced in case of success, and ",[75,3656,3616],{}," represents the type of the error produced in case of failure.",[22,3659],{"className":3660},[25],[27,3662,3663],{},"For example, consider a function that parses a string into an integer:",[22,3665],{"className":3666},[25],[337,3668,3670],{"className":339,"code":3669,"filename":341,"language":249,"meta":231,"style":231},"fn parse_int(s: &str) -> Result\u003Ci32, std::num::ParseIntError> {\n    match s.parse::\u003Ci32>() {\n        Ok(num) => Ok(num),\n        Err(err) => Err(err),\n    }\n}\n\nfn main() {\n    let input_string = \"42\";\n    match parse_int(input_string) {\n        Ok(num) => println!(\"Parsed number: {}\", num),\n        Err(err) => eprintln!(\"Error while parsing: {}\", err),\n    }\n}\n",[75,3671,3672,3713,3734,3750,3766,3770,3774,3778,3786,3800,3809,3828,3847,3851],{"__ignoreMap":231},[345,3673,3674,3676,3679,3681,3683,3685,3688,3690,3692,3694,3696,3698,3701,3703,3706,3708,3711],{"class":347,"line":348},[345,3675,352],{"class":351},[345,3677,3678],{"class":355}," parse_int",[345,3680,1458],{"class":359},[345,3682,530],{"class":351},[345,3684,1608],{"class":351},[345,3686,3687],{"class":355},"str",[345,3689,544],{"class":359},[345,3691,547],{"class":351},[345,3693,3606],{"class":355},[345,3695,521],{"class":359},[345,3697,570],{"class":355},[345,3699,3700],{"class":359},", std",[345,3702,1256],{"class":351},[345,3704,3705],{"class":359},"num",[345,3707,1256],{"class":351},[345,3709,3710],{"class":355},"ParseIntError",[345,3712,3619],{"class":359},[345,3714,3715,3717,3720,3722,3725,3727,3729,3731],{"class":347,"line":232},[345,3716,1772],{"class":351},[345,3718,3719],{"class":359}," s",[345,3721,139],{"class":351},[345,3723,3724],{"class":355},"parse",[345,3726,1256],{"class":351},[345,3728,521],{"class":359},[345,3730,570],{"class":355},[345,3732,3733],{"class":359},">() {\n",[345,3735,3736,3739,3742,3744,3747],{"class":347,"line":385},[345,3737,3738],{"class":355},"        Ok",[345,3740,3741],{"class":359},"(num) ",[345,3743,1822],{"class":351},[345,3745,3746],{"class":355}," Ok",[345,3748,3749],{"class":359},"(num),\n",[345,3751,3752,3755,3758,3760,3763],{"class":347,"line":398},[345,3753,3754],{"class":355},"        Err",[345,3756,3757],{"class":359},"(err) ",[345,3759,1822],{"class":351},[345,3761,3762],{"class":355}," Err",[345,3764,3765],{"class":359},"(err),\n",[345,3767,3768],{"class":347,"line":416},[345,3769,866],{"class":359},[345,3771,3772],{"class":347,"line":428},[345,3773,472],{"class":359},[345,3775,3776],{"class":347,"line":434},[345,3777,606],{"emptyLinePlaceholder":242},[345,3779,3780,3782,3784],{"class":347,"line":453},[345,3781,352],{"class":351},[345,3783,356],{"class":355},[345,3785,360],{"class":359},[345,3787,3788,3790,3793,3795,3798],{"class":347,"line":469},[345,3789,365],{"class":351},[345,3791,3792],{"class":359}," input_string ",[345,3794,371],{"class":351},[345,3796,3797],{"class":443}," \"42\"",[345,3799,1048],{"class":359},[345,3801,3802,3804,3806],{"class":347,"line":640},[345,3803,1772],{"class":351},[345,3805,3678],{"class":355},[345,3807,3808],{"class":359},"(input_string) {\n",[345,3810,3811,3813,3815,3817,3820,3822,3825],{"class":347,"line":645},[345,3812,3738],{"class":355},[345,3814,3741],{"class":359},[345,3816,1822],{"class":351},[345,3818,3819],{"class":355}," println!",[345,3821,440],{"class":359},[345,3823,3824],{"class":443},"\"Parsed number: {}\"",[345,3826,3827],{"class":359},", num),\n",[345,3829,3830,3832,3834,3836,3839,3841,3844],{"class":347,"line":650},[345,3831,3754],{"class":355},[345,3833,3757],{"class":359},[345,3835,1822],{"class":351},[345,3837,3838],{"class":355}," eprintln!",[345,3840,440],{"class":359},[345,3842,3843],{"class":443},"\"Error while parsing: {}\"",[345,3845,3846],{"class":359},", err),\n",[345,3848,3849],{"class":347,"line":659},[345,3850,866],{"class":359},[345,3852,3853],{"class":347,"line":680},[345,3854,472],{"class":359},[22,3856],{"className":3857},[25],[27,3859,704,3860,3863,3864,3867,3868,3870,3871,3874,3875,3878,3879,3882,3883,3886],{},[75,3861,3862],{},"parse_int"," function takes a string ",[75,3865,3866],{},"s"," as input and attempts to parse it into an ",[75,3869,570],{},". If the parsing is successful (",[75,3872,3873],{},"Ok(num)","), the function returns ",[75,3876,3877],{},"Ok"," with the parsed number. Otherwise, it returns ",[75,3880,3881],{},"Err"," with the specific parsing error (",[75,3884,3885],{},"std::num::ParseIntError",").",[27,3888,3889,3890,3892,3893,3895],{},"In the ",[75,3891,2173],{}," function, we call ",[75,3894,3862],{}," with the input string \"42\". If the parsing succeeds, we print the parsed number. If it fails, we print the specific error message.",[22,3897],{"className":3898},[14],[305,3900,3902],{"id":3901},"option-type","Option Type",[27,3904,3905,3906,3908,3909,3911],{},"In Rust, the ",[75,3907,3576],{}," type is another built-in enum used to represent the presence or absence of a value. It is commonly used when a function can return either a valid value or nothing (null). The ",[75,3910,3576],{}," enum is defined as follows:",[22,3913],{"className":3914},[25],[337,3916,3918],{"className":339,"code":3917,"filename":341,"language":249,"meta":231,"style":231},"enum Option\u003CT> {\n    Some(T),\n    None,\n}\n",[75,3919,3920,3933,3944,3951],{"__ignoreMap":231},[345,3921,3922,3924,3927,3929,3931],{"class":347,"line":348},[345,3923,1697],{"class":351},[345,3925,3926],{"class":355}," Option",[345,3928,521],{"class":359},[345,3930,3611],{"class":355},[345,3932,3619],{"class":359},[345,3934,3935,3938,3940,3942],{"class":347,"line":232},[345,3936,3937],{"class":355},"    Some",[345,3939,440],{"class":359},[345,3941,3611],{"class":355},[345,3943,1743],{"class":359},[345,3945,3946,3949],{"class":347,"line":385},[345,3947,3948],{"class":355},"    None",[345,3950,579],{"class":359},[345,3952,3953],{"class":347,"line":398},[345,3954,472],{"class":359},[22,3956],{"className":3957},[25],[27,3959,3651,3960,3962,3963,3966,3967,3580,3969,3971,3972,3975],{},[75,3961,3611],{}," represents the type of value that may be present inside ",[75,3964,3965],{},"Some",". The ",[75,3968,3576],{},[75,3970,3965],{},", which holds the value, and ",[75,3973,3974],{},"None",", which represents the absence of a value.",[22,3977],{"className":3978},[25],[27,3980,3981,3982,3984],{},"Using ",[75,3983,3576],{}," is Rust's preferred way of handling cases where a value might be missing, instead of using null or other unsafe approaches. This helps to avoid null pointer dereference errors and encourages safer and more explicit code.",[27,3986,3987,3988,3990,3991,125,3993,125,3995,125,3998,4001,4002,4005],{},"To work with ",[75,3989,3576],{},", developers typically use pattern matching or combinators like ",[75,3992,2994],{},[75,3994,3064],{},[75,3996,3997],{},"map",[75,3999,4000],{},"and_then"," (also known as ",[75,4003,4004],{},"flatMap","), etc., to access the value or handle the absence of a value gracefully.",[27,4007,4008,4009,530],{},"Here's a simple example that demonstrates the use of ",[75,4010,3576],{},[22,4012],{"className":4013},[25],[337,4015,4017],{"className":339,"code":4016,"filename":341,"language":249,"meta":231,"style":231},"fn find_max(numbers: &[i32]) -> Option\u003Ci32> {\n    if numbers.is_empty() {\n        None\n    } else {\n        let mut max = numbers[0];\n        for &num in numbers.iter() {\n            if num > max {\n                max = num;\n            }\n        }\n        Some(max)\n    }\n}\n\nfn main() {\n    let numbers = vec![10, 7, 25, 12, 3];\n    match find_max(&numbers) {\n        Some(max) => println!(\"Maximum value: {}\", max),\n        None => println!(\"No values found.\"),\n    }\n}\n",[75,4018,4019,4050,4064,4069,4077,4096,4117,4131,4141,4146,4150,4158,4162,4166,4170,4178,4215,4228,4247,4263,4267],{"__ignoreMap":231},[345,4020,4021,4023,4026,4029,4031,4033,4035,4037,4040,4042,4044,4046,4048],{"class":347,"line":348},[345,4022,352],{"class":351},[345,4024,4025],{"class":355}," find_max",[345,4027,4028],{"class":359},"(numbers",[345,4030,530],{"class":351},[345,4032,1608],{"class":351},[345,4034,1251],{"class":359},[345,4036,570],{"class":355},[345,4038,4039],{"class":359},"]) ",[345,4041,547],{"class":351},[345,4043,3926],{"class":355},[345,4045,521],{"class":359},[345,4047,570],{"class":355},[345,4049,3619],{"class":359},[345,4051,4052,4054,4057,4059,4062],{"class":347,"line":232},[345,4053,2248],{"class":351},[345,4055,4056],{"class":359}," numbers",[345,4058,139],{"class":351},[345,4060,4061],{"class":355},"is_empty",[345,4063,360],{"class":359},[345,4065,4066],{"class":347,"line":385},[345,4067,4068],{"class":355},"        None\n",[345,4070,4071,4073,4075],{"class":347,"line":398},[345,4072,2274],{"class":359},[345,4074,2277],{"class":351},[345,4076,395],{"class":359},[345,4078,4079,4081,4083,4086,4088,4091,4093],{"class":347,"line":416},[345,4080,401],{"class":351},[345,4082,2647],{"class":351},[345,4084,4085],{"class":359}," max ",[345,4087,371],{"class":351},[345,4089,4090],{"class":359}," numbers[",[345,4092,2875],{"class":374},[345,4094,4095],{"class":359},"];\n",[345,4097,4098,4101,4103,4106,4108,4110,4112,4115],{"class":347,"line":428},[345,4099,4100],{"class":351},"        for",[345,4102,1608],{"class":351},[345,4104,4105],{"class":359},"num ",[345,4107,1288],{"class":351},[345,4109,4056],{"class":359},[345,4111,139],{"class":351},[345,4113,4114],{"class":355},"iter",[345,4116,360],{"class":359},[345,4118,4119,4122,4125,4128],{"class":347,"line":434},[345,4120,4121],{"class":351},"            if",[345,4123,4124],{"class":359}," num ",[345,4126,4127],{"class":351},">",[345,4129,4130],{"class":359}," max {\n",[345,4132,4133,4136,4138],{"class":347,"line":453},[345,4134,4135],{"class":359},"                max ",[345,4137,371],{"class":351},[345,4139,4140],{"class":359}," num;\n",[345,4142,4143],{"class":347,"line":469},[345,4144,4145],{"class":359},"            }\n",[345,4147,4148],{"class":347,"line":640},[345,4149,1807],{"class":359},[345,4151,4152,4155],{"class":347,"line":645},[345,4153,4154],{"class":355},"        Some",[345,4156,4157],{"class":359},"(max)\n",[345,4159,4160],{"class":347,"line":650},[345,4161,866],{"class":359},[345,4163,4164],{"class":347,"line":659},[345,4165,472],{"class":359},[345,4167,4168],{"class":347,"line":680},[345,4169,606],{"emptyLinePlaceholder":242},[345,4171,4172,4174,4176],{"class":347,"line":696},[345,4173,352],{"class":351},[345,4175,356],{"class":355},[345,4177,360],{"class":359},[345,4179,4180,4182,4185,4187,4189,4191,4193,4195,4198,4200,4203,4205,4208,4210,4213],{"class":347,"line":921},[345,4181,365],{"class":351},[345,4183,4184],{"class":359}," numbers ",[345,4186,371],{"class":351},[345,4188,1248],{"class":355},[345,4190,1251],{"class":359},[345,4192,1981],{"class":374},[345,4194,125],{"class":359},[345,4196,4197],{"class":374},"7",[345,4199,125],{"class":359},[345,4201,4202],{"class":374},"25",[345,4204,125],{"class":359},[345,4206,4207],{"class":374},"12",[345,4209,125],{"class":359},[345,4211,4212],{"class":374},"3",[345,4214,4095],{"class":359},[345,4216,4217,4219,4221,4223,4225],{"class":347,"line":926},[345,4218,1772],{"class":351},[345,4220,4025],{"class":355},[345,4222,440],{"class":359},[345,4224,829],{"class":351},[345,4226,4227],{"class":359},"numbers) {\n",[345,4229,4230,4232,4235,4237,4239,4241,4244],{"class":347,"line":950},[345,4231,4154],{"class":355},[345,4233,4234],{"class":359},"(max) ",[345,4236,1822],{"class":351},[345,4238,3819],{"class":355},[345,4240,440],{"class":359},[345,4242,4243],{"class":443},"\"Maximum value: {}\"",[345,4245,4246],{"class":359},", max),\n",[345,4248,4249,4252,4254,4256,4258,4261],{"class":347,"line":1161},[345,4250,4251],{"class":355},"        None",[345,4253,1788],{"class":351},[345,4255,3819],{"class":355},[345,4257,440],{"class":359},[345,4259,4260],{"class":443},"\"No values found.\"",[345,4262,1743],{"class":359},[345,4264,4265],{"class":347,"line":1166},[345,4266,866],{"class":359},[345,4268,4269],{"class":347,"line":1175},[345,4270,472],{"class":359},[22,4272],{"className":4273},[25],[27,4275,4276,4277,4280,4281,4283,4284,4287,4288,4291,4292,4294,4295,139],{},"In the example above, the ",[75,4278,4279],{},"find_max"," function takes a slice of ",[75,4282,570],{}," numbers as input and returns an ",[75,4285,4286],{},"Option\u003Ci32>",". If the ",[75,4289,4290],{},"numbers"," slice is empty, it returns ",[75,4293,3974],{},". Otherwise, it iterates through the numbers to find the maximum value and returns it wrapped in ",[75,4296,3965],{},[27,4298,3889,4299,3892,4301,4303,4304,4306,4307,139],{},[75,4300,2173],{},[75,4302,4279],{}," with a vector of numbers. We then pattern match on the result of ",[75,4305,4279],{},", printing the maximum value if it exists or indicating that no values were found if the result is ",[75,4308,3974],{},[22,4310],{"className":4311},[14],[22,4313],{"className":4314},[14],[60,4316,4318],{"id":4317},"propagating-errors-with-the-operator","Propagating Errors with the ? Operator",[27,4320,4321,4322,4325,4326,966,4328,4330,4331,4333,4334,4336],{},"The ",[75,4323,4324],{},"?"," operator in Rust is a powerful tool for concise error handling and can be used with both ",[75,4327,3573],{},[75,4329,3576],{}," types. When used within functions that return a ",[75,4332,3573],{}," or ",[75,4335,3576],{},", it simplifies error propagation and handling.",[27,4338,4339,4340,4342,4343,966,4345,4347],{},"Let's see how the ",[75,4341,4324],{}," operator is used in both ",[75,4344,3573],{},[75,4346,3576],{}," contexts with code examples:",[22,4349],{"className":4350},[14],[305,4352,4354],{"id":4353},"using-with-result","Using ? with Result",[22,4356],{"className":4357},[25],[337,4359,4361],{"className":339,"code":4360,"filename":341,"language":249,"meta":231,"style":231},"use std::fs::File;\nuse std::io::Read;\n\nfn read_file_contents(filename: &str) -> Result\u003CString, std::io::Error> {\n    let mut file = File::open(filename)?; // The ? operator handles the potential error here.\n    let mut contents = String::new();\n    file.read_to_string(&mut contents)?; // The ? operator handles the potential error here.\n    Ok(contents)\n}\n\nfn main() {\n    match read_file_contents(\"example.txt\") {\n        Ok(contents) => println!(\"File contents: {}\", contents),\n        Err(err) => eprintln!(\"Error reading file: {}\", err),\n    }\n}\n",[75,4362,4363,4381,4399,4403,4442,4471,4490,4513,4520,4524,4528,4536,4549,4568,4585,4589],{"__ignoreMap":231},[345,4364,4365,4367,4369,4371,4374,4376,4379],{"class":347,"line":348},[345,4366,2800],{"class":351},[345,4368,2803],{"class":355},[345,4370,1256],{"class":351},[345,4372,4373],{"class":355},"fs",[345,4375,1256],{"class":351},[345,4377,4378],{"class":355},"File",[345,4380,1048],{"class":359},[345,4382,4383,4385,4387,4389,4392,4394,4397],{"class":347,"line":232},[345,4384,2800],{"class":351},[345,4386,2803],{"class":355},[345,4388,1256],{"class":351},[345,4390,4391],{"class":355},"io",[345,4393,1256],{"class":351},[345,4395,4396],{"class":355},"Read",[345,4398,1048],{"class":359},[345,4400,4401],{"class":347,"line":385},[345,4402,606],{"emptyLinePlaceholder":242},[345,4404,4405,4407,4410,4413,4415,4417,4419,4421,4423,4425,4427,4429,4431,4433,4435,4437,4440],{"class":347,"line":398},[345,4406,352],{"class":351},[345,4408,4409],{"class":355}," read_file_contents",[345,4411,4412],{"class":359},"(filename",[345,4414,530],{"class":351},[345,4416,1608],{"class":351},[345,4418,3687],{"class":355},[345,4420,544],{"class":359},[345,4422,547],{"class":351},[345,4424,3606],{"class":355},[345,4426,521],{"class":359},[345,4428,1611],{"class":355},[345,4430,3700],{"class":359},[345,4432,1256],{"class":351},[345,4434,4391],{"class":359},[345,4436,1256],{"class":351},[345,4438,4439],{"class":355},"Error",[345,4441,3619],{"class":359},[345,4443,4444,4446,4448,4451,4453,4456,4458,4461,4464,4466,4468],{"class":347,"line":416},[345,4445,365],{"class":351},[345,4447,2647],{"class":351},[345,4449,4450],{"class":359}," file ",[345,4452,371],{"class":351},[345,4454,4455],{"class":355}," File",[345,4457,1256],{"class":351},[345,4459,4460],{"class":355},"open",[345,4462,4463],{"class":359},"(filename)",[345,4465,4324],{"class":351},[345,4467,378],{"class":359},[345,4469,4470],{"class":381},"// The ? operator handles the potential error here.\n",[345,4472,4473,4475,4477,4480,4482,4484,4486,4488],{"class":347,"line":428},[345,4474,365],{"class":351},[345,4476,2647],{"class":351},[345,4478,4479],{"class":359}," contents ",[345,4481,371],{"class":351},[345,4483,1397],{"class":355},[345,4485,1256],{"class":351},[345,4487,1259],{"class":355},[345,4489,1305],{"class":359},[345,4491,4492,4495,4497,4500,4502,4504,4507,4509,4511],{"class":347,"line":434},[345,4493,4494],{"class":359},"    file",[345,4496,139],{"class":351},[345,4498,4499],{"class":355},"read_to_string",[345,4501,440],{"class":359},[345,4503,2729],{"class":351},[345,4505,4506],{"class":359}," contents)",[345,4508,4324],{"class":351},[345,4510,378],{"class":359},[345,4512,4470],{"class":381},[345,4514,4515,4517],{"class":347,"line":453},[345,4516,3624],{"class":355},[345,4518,4519],{"class":359},"(contents)\n",[345,4521,4522],{"class":347,"line":469},[345,4523,472],{"class":359},[345,4525,4526],{"class":347,"line":640},[345,4527,606],{"emptyLinePlaceholder":242},[345,4529,4530,4532,4534],{"class":347,"line":645},[345,4531,352],{"class":351},[345,4533,356],{"class":355},[345,4535,360],{"class":359},[345,4537,4538,4540,4542,4544,4547],{"class":347,"line":650},[345,4539,1772],{"class":351},[345,4541,4409],{"class":355},[345,4543,440],{"class":359},[345,4545,4546],{"class":443},"\"example.txt\"",[345,4548,1089],{"class":359},[345,4550,4551,4553,4556,4558,4560,4562,4565],{"class":347,"line":659},[345,4552,3738],{"class":355},[345,4554,4555],{"class":359},"(contents) ",[345,4557,1822],{"class":351},[345,4559,3819],{"class":355},[345,4561,440],{"class":359},[345,4563,4564],{"class":443},"\"File contents: {}\"",[345,4566,4567],{"class":359},", contents),\n",[345,4569,4570,4572,4574,4576,4578,4580,4583],{"class":347,"line":680},[345,4571,3754],{"class":355},[345,4573,3757],{"class":359},[345,4575,1822],{"class":351},[345,4577,3838],{"class":355},[345,4579,440],{"class":359},[345,4581,4582],{"class":443},"\"Error reading file: {}\"",[345,4584,3846],{"class":359},[345,4586,4587],{"class":347,"line":696},[345,4588,866],{"class":359},[345,4590,4591],{"class":347,"line":921},[345,4592,472],{"class":359},[22,4594],{"className":4595},[25],[27,4597,4598,4599,4602,4603,4606,4607,4610,4611,4613,4614,966,4617,4619,4620,4622,4623,4625],{},"In the above example, the ",[75,4600,4601],{},"read_file_contents"," function returns a ",[75,4604,4605],{},"Result\u003CString, std::io::Error>",", representing the contents of a file or an ",[75,4608,4609],{},"io::Error"," if the file cannot be read. The ",[75,4612,4324],{}," operator is used to propagate errors from the ",[75,4615,4616],{},"File::open",[75,4618,4499],{}," methods automatically. If either of these methods returns an error, the ",[75,4621,4324],{}," operator will return the error immediately, and the ",[75,4624,2173],{}," function can handle it appropriately.",[22,4627],{"className":4628},[25],[305,4630,4632],{"id":4631},"using-with-option","Using ? with Option",[27,4634,4635,4636,4638,4639,4641,4642,4644,4645,4647,4648,139],{},"If an ",[75,4637,3576],{}," value is ",[75,4640,3965],{},", the ",[75,4643,4324],{}," operator will unwrap the value; if it is ",[75,4646,3974],{},", it will return ",[75,4649,3974],{},[22,4651],{"className":4652},[25],[337,4654,4656],{"className":339,"code":4655,"filename":341,"language":249,"meta":231,"style":231},"fn try_option_some() -> Option\u003Cu8> {\n    let val = Some(1)?;\n    Some(val)\n}\n\nfn try_option_none() -> Option\u003Cu8> {\n    let val = None?;\n    Some(val)\n}\n\nfn main() {\n    assert_eq!(try_option_some(), Some(1));\n    assert_eq!(try_option_none(), None);\n}\n",[75,4657,4658,4678,4702,4709,4713,4717,4736,4751,4757,4761,4765,4773,4794,4809],{"__ignoreMap":231},[345,4659,4660,4662,4665,4667,4669,4671,4673,4676],{"class":347,"line":348},[345,4661,352],{"class":351},[345,4663,4664],{"class":355}," try_option_some",[345,4666,2060],{"class":359},[345,4668,547],{"class":351},[345,4670,3926],{"class":355},[345,4672,521],{"class":359},[345,4674,4675],{"class":355},"u8",[345,4677,3619],{"class":359},[345,4679,4680,4682,4685,4687,4690,4692,4695,4698,4700],{"class":347,"line":232},[345,4681,365],{"class":351},[345,4683,4684],{"class":359}," val ",[345,4686,371],{"class":351},[345,4688,4689],{"class":355}," Some",[345,4691,440],{"class":359},[345,4693,4694],{"class":374},"1",[345,4696,4697],{"class":359},")",[345,4699,4324],{"class":351},[345,4701,1048],{"class":359},[345,4703,4704,4706],{"class":347,"line":385},[345,4705,3937],{"class":355},[345,4707,4708],{"class":359},"(val)\n",[345,4710,4711],{"class":347,"line":398},[345,4712,472],{"class":359},[345,4714,4715],{"class":347,"line":416},[345,4716,606],{"emptyLinePlaceholder":242},[345,4718,4719,4721,4724,4726,4728,4730,4732,4734],{"class":347,"line":428},[345,4720,352],{"class":351},[345,4722,4723],{"class":355}," try_option_none",[345,4725,2060],{"class":359},[345,4727,547],{"class":351},[345,4729,3926],{"class":355},[345,4731,521],{"class":359},[345,4733,4675],{"class":355},[345,4735,3619],{"class":359},[345,4737,4738,4740,4742,4744,4747,4749],{"class":347,"line":434},[345,4739,365],{"class":351},[345,4741,4684],{"class":359},[345,4743,371],{"class":351},[345,4745,4746],{"class":355}," None",[345,4748,4324],{"class":351},[345,4750,1048],{"class":359},[345,4752,4753,4755],{"class":347,"line":453},[345,4754,3937],{"class":355},[345,4756,4708],{"class":359},[345,4758,4759],{"class":347,"line":469},[345,4760,472],{"class":359},[345,4762,4763],{"class":347,"line":640},[345,4764,606],{"emptyLinePlaceholder":242},[345,4766,4767,4769,4771],{"class":347,"line":645},[345,4768,352],{"class":351},[345,4770,356],{"class":355},[345,4772,360],{"class":359},[345,4774,4775,4778,4780,4783,4786,4788,4790,4792],{"class":347,"line":650},[345,4776,4777],{"class":355},"    assert_eq!",[345,4779,440],{"class":359},[345,4781,4782],{"class":355},"try_option_some",[345,4784,4785],{"class":359},"(), ",[345,4787,3965],{"class":355},[345,4789,440],{"class":359},[345,4791,4694],{"class":374},[345,4793,2878],{"class":359},[345,4795,4796,4798,4800,4803,4805,4807],{"class":347,"line":659},[345,4797,4777],{"class":355},[345,4799,440],{"class":359},[345,4801,4802],{"class":355},"try_option_none",[345,4804,4785],{"class":359},[345,4806,3974],{"class":355},[345,4808,677],{"class":359},[345,4810,4811],{"class":347,"line":680},[345,4812,472],{"class":359},[22,4814],{"className":4815},[25],[27,4817,3889,4818,4820,4821,4824,4825,4827,4828,4641,4830,4832,4833,4836,4837,4839,4840,4843],{},[75,4819,4782],{}," function, we start with ",[75,4822,4823],{},"Some(1)",", and then we use the ",[75,4826,4324],{}," operator. Since the value is ",[75,4829,3965],{},[75,4831,4324],{}," operator will unwrap the value, resulting in ",[75,4834,4835],{},"val"," being assigned ",[75,4838,4694],{},". The function then returns ",[75,4841,4842],{},"Some(val)"," with the unwrapped value.",[27,4845,3889,4846,4820,4848,4824,4850,4827,4852,4641,4854,4856,4857,4859],{},[75,4847,4802],{},[75,4849,3974],{},[75,4851,4324],{},[75,4853,3974],{},[75,4855,4324],{}," operator will immediately return ",[75,4858,3974],{},", and the function will end without further execution.",[27,4861,4862,4863,4865,4866,4868,4869,4871,4872,4868,4874,4876],{},"When we run the ",[75,4864,2173],{}," function, it will assert that the result of ",[75,4867,4782],{}," is ",[75,4870,4823],{},", and the result of ",[75,4873,4802],{},[75,4875,3974],{},", and both assertions will pass.",[27,4878,4879,4880,4882,4883,4885,4886,4888,4889,4891],{},"This demonstrates how the ",[75,4881,4324],{}," operator can be used with ",[75,4884,3576],{}," to handle the possibility of ",[75,4887,3974],{}," and return early if necessary. It simplifies the code by allowing the early return of ",[75,4890,3974],{}," if the value is not present, without the need for manual pattern matching.",[22,4893],{"className":4894},[14],[22,4896],{"className":4897},[14],[60,4899,4901],{"id":4900},"custom-error-types","Custom Error Types",[27,4903,4904,4905,4908],{},"While Rust's standard library provides a wide range of predefined error types, developers often need to define their custom error types to express specific failure scenarios. By implementing the ",[75,4906,4907],{},"std::error::Error"," trait, developers can create their error types and provide meaningful error messages and additional context.",[22,4910],{"className":4911},[25],[337,4913,4915],{"className":339,"code":4914,"filename":341,"language":249,"meta":231,"style":231},"use std::error::Error;\nuse std::fmt;\n\n#[derive(Debug)]\nstruct CustomError {\n    message: String,\n}\n\nimpl Error for CustomError {}\n\nimpl fmt::Display for CustomError {\n    fn fmt(&self, f: &mut fmt::Formatter\u003C'_>) -> fmt::Result {\n        write!(f, \"{}\", self.message)\n    }\n}\n\nfn process_data(data: &[u8]) -> Result\u003C(), CustomError> {\n    // Error condition\n    if data.len() == 0 {\n        return Err(CustomError {\n            message: \"Empty data provided.\".to_owned(),\n        });\n    }\n    // Process data here...\n    Ok(())\n}\n",[75,4916,4917,4934,4945,4949,4960,4969,4980,4984,4988,5002,5006,5024,5068,5088,5092,5096,5100,5132,5137,5157,5170,5188,5192,5196,5201,5208],{"__ignoreMap":231},[345,4918,4919,4921,4923,4925,4928,4930,4932],{"class":347,"line":348},[345,4920,2800],{"class":351},[345,4922,2803],{"class":355},[345,4924,1256],{"class":351},[345,4926,4927],{"class":355},"error",[345,4929,1256],{"class":351},[345,4931,4439],{"class":355},[345,4933,1048],{"class":359},[345,4935,4936,4938,4940,4942],{"class":347,"line":232},[345,4937,2800],{"class":351},[345,4939,2803],{"class":355},[345,4941,1256],{"class":351},[345,4943,4944],{"class":359},"fmt;\n",[345,4946,4947],{"class":347,"line":385},[345,4948,606],{"emptyLinePlaceholder":242},[345,4950,4951,4954,4957],{"class":347,"line":398},[345,4952,4953],{"class":359},"#[derive(",[345,4955,4956],{"class":355},"Debug",[345,4958,4959],{"class":359},")]\n",[345,4961,4962,4964,4967],{"class":347,"line":416},[345,4963,771],{"class":351},[345,4965,4966],{"class":355}," CustomError",[345,4968,395],{"class":359},[345,4970,4971,4974,4976,4978],{"class":347,"line":428},[345,4972,4973],{"class":359},"    message",[345,4975,530],{"class":351},[345,4977,1397],{"class":355},[345,4979,579],{"class":359},[345,4981,4982],{"class":347,"line":434},[345,4983,472],{"class":359},[345,4985,4986],{"class":347,"line":453},[345,4987,606],{"emptyLinePlaceholder":242},[345,4989,4990,4992,4995,4997,4999],{"class":347,"line":469},[345,4991,812],{"class":351},[345,4993,4994],{"class":355}," Error",[345,4996,1070],{"class":351},[345,4998,4966],{"class":355},[345,5000,5001],{"class":359}," {}\n",[345,5003,5004],{"class":347,"line":640},[345,5005,606],{"emptyLinePlaceholder":242},[345,5007,5008,5010,5013,5015,5018,5020,5022],{"class":347,"line":645},[345,5009,812],{"class":351},[345,5011,5012],{"class":355}," fmt",[345,5014,1256],{"class":351},[345,5016,5017],{"class":355},"Display",[345,5019,1070],{"class":351},[345,5021,4966],{"class":355},[345,5023,395],{"class":359},[345,5025,5026,5028,5030,5032,5034,5036,5039,5041,5043,5045,5047,5050,5052,5055,5058,5060,5062,5064,5066],{"class":347,"line":650},[345,5027,821],{"class":351},[345,5029,5012],{"class":355},[345,5031,440],{"class":359},[345,5033,829],{"class":351},[345,5035,832],{"class":374},[345,5037,5038],{"class":359},", f",[345,5040,530],{"class":351},[345,5042,2668],{"class":351},[345,5044,5012],{"class":355},[345,5046,1256],{"class":351},[345,5048,5049],{"class":355},"Formatter",[345,5051,2200],{"class":359},[345,5053,5054],{"class":355},"_",[345,5056,5057],{"class":359},">) ",[345,5059,547],{"class":351},[345,5061,5012],{"class":355},[345,5063,1256],{"class":351},[345,5065,3573],{"class":355},[345,5067,395],{"class":359},[345,5069,5070,5073,5076,5079,5081,5083,5085],{"class":347,"line":659},[345,5071,5072],{"class":355},"        write!",[345,5074,5075],{"class":359},"(f, ",[345,5077,5078],{"class":443},"\"{}\"",[345,5080,125],{"class":359},[345,5082,832],{"class":374},[345,5084,139],{"class":351},[345,5086,5087],{"class":359},"message)\n",[345,5089,5090],{"class":347,"line":680},[345,5091,866],{"class":359},[345,5093,5094],{"class":347,"line":696},[345,5095,472],{"class":359},[345,5097,5098],{"class":347,"line":921},[345,5099,606],{"emptyLinePlaceholder":242},[345,5101,5102,5104,5107,5110,5112,5114,5116,5118,5120,5122,5124,5127,5130],{"class":347,"line":926},[345,5103,352],{"class":351},[345,5105,5106],{"class":355}," process_data",[345,5108,5109],{"class":359},"(data",[345,5111,530],{"class":351},[345,5113,1608],{"class":351},[345,5115,1251],{"class":359},[345,5117,4675],{"class":355},[345,5119,4039],{"class":359},[345,5121,547],{"class":351},[345,5123,3606],{"class":355},[345,5125,5126],{"class":359},"\u003C(), ",[345,5128,5129],{"class":355},"CustomError",[345,5131,3619],{"class":359},[345,5133,5134],{"class":347,"line":950},[345,5135,5136],{"class":381},"    // Error condition\n",[345,5138,5139,5141,5144,5146,5148,5150,5153,5155],{"class":347,"line":1161},[345,5140,2248],{"class":351},[345,5142,5143],{"class":359}," data",[345,5145,139],{"class":351},[345,5147,1640],{"class":355},[345,5149,2060],{"class":359},[345,5151,5152],{"class":351},"==",[345,5154,2910],{"class":374},[345,5156,395],{"class":359},[345,5158,5159,5162,5164,5166,5168],{"class":347,"line":1166},[345,5160,5161],{"class":351},"        return",[345,5163,3762],{"class":355},[345,5165,440],{"class":359},[345,5167,5129],{"class":355},[345,5169,395],{"class":359},[345,5171,5172,5175,5177,5180,5182,5185],{"class":347,"line":1175},[345,5173,5174],{"class":359},"            message",[345,5176,530],{"class":351},[345,5178,5179],{"class":443}," \"Empty data provided.\"",[345,5181,139],{"class":351},[345,5183,5184],{"class":355},"to_owned",[345,5186,5187],{"class":359},"(),\n",[345,5189,5190],{"class":347,"line":1194},[345,5191,3015],{"class":359},[345,5193,5194],{"class":347,"line":1212},[345,5195,866],{"class":359},[345,5197,5198],{"class":347,"line":1218},[345,5199,5200],{"class":381},"    // Process data here...\n",[345,5202,5203,5205],{"class":347,"line":1274},[345,5204,3624],{"class":355},[345,5206,5207],{"class":359},"(())\n",[345,5209,5210],{"class":347,"line":1279},[345,5211,472],{"class":359},[22,5213],{"className":5214},[25],[27,5216,4276,5217,5219,5220,5222,5223,5225],{},[75,5218,5129],{}," struct implements the ",[75,5221,4439],{}," trait, enabling it to be used as an error type in the ",[75,5224,3573],{}," enum.",[22,5227],{"className":5228},[14],[22,5230],{"className":5231},[14],[60,5233,5235],{"id":5234},"unrecoverable-errors-with-panic","Unrecoverable Errors with panic!",[27,5237,5238,5239,5242,5243,5245],{},"In some cases, when encountering unrecoverable errors, it is appropriate to use the ",[75,5240,5241],{},"panic!"," macro. It causes the program to terminate, unwinding the stack and printing an error message. ",[75,5244,5241],{}," is typically used for critical errors that indicate a bug or invalid program state.",[22,5247],{"className":5248},[25],[337,5250,5252],{"className":339,"code":5251,"filename":341,"language":249,"meta":231,"style":231},"fn divide(a: i32, b: i32) -> i32 {\n    if b == 0 {\n        panic!(\"Cannot divide by zero.\");\n    }\n    a / b\n}\n",[75,5253,5254,5283,5296,5308,5312,5323],{"__ignoreMap":231},[345,5255,5256,5258,5261,5264,5266,5268,5271,5273,5275,5277,5279,5281],{"class":347,"line":348},[345,5257,352],{"class":351},[345,5259,5260],{"class":355}," divide",[345,5262,5263],{"class":359},"(a",[345,5265,530],{"class":351},[345,5267,541],{"class":355},[345,5269,5270],{"class":359},", b",[345,5272,530],{"class":351},[345,5274,541],{"class":355},[345,5276,544],{"class":359},[345,5278,547],{"class":351},[345,5280,541],{"class":355},[345,5282,395],{"class":359},[345,5284,5285,5287,5290,5292,5294],{"class":347,"line":232},[345,5286,2248],{"class":351},[345,5288,5289],{"class":359}," b ",[345,5291,5152],{"class":351},[345,5293,2910],{"class":374},[345,5295,395],{"class":359},[345,5297,5298,5301,5303,5306],{"class":347,"line":385},[345,5299,5300],{"class":355},"        panic!",[345,5302,440],{"class":359},[345,5304,5305],{"class":443},"\"Cannot divide by zero.\"",[345,5307,677],{"class":359},[345,5309,5310],{"class":347,"line":398},[345,5311,866],{"class":359},[345,5313,5314,5317,5320],{"class":347,"line":416},[345,5315,5316],{"class":359},"    a ",[345,5318,5319],{"class":351},"/",[345,5321,5322],{"class":359}," b\n",[345,5324,5325],{"class":347,"line":428},[345,5326,472],{"class":359},[22,5328],{"className":5329},[25],[27,5331,5332,5333,5336],{},"In the above example, if the divisor ",[75,5334,5335],{},"b"," is zero, the program will panic and display the provided error message.",[22,5338],{"className":5339},[14],[22,5341],{"className":5342},[14],[60,5344,3166],{"id":3165},[27,5346,5347,5348,966,5350,5352,5353,5355,5356,5358],{},"Rust provides a robust and expressive set of error handling mechanisms, promoting safe and reliable software development. By leveraging the ",[75,5349,3573],{},[75,5351,3576],{}," enums, propagating errors with the ",[75,5354,4324],{}," operator, defining custom error types, and utilizing the ",[75,5357,5241],{}," macro when appropriate, developers can build robust and maintainable codebases.",[27,5360,5361],{},"Error handling in Rust encourages developers to be explicit about handling potential failures, leading to more reliable and predictable software.",[22,5363],{"className":5364},[14],[3180,5366],{},[22,5368],{"className":5369},[14],[27,5371,5372],{},[3188,5373,3190,5374,3498],{},[31,5375,3195],{"href":5376,"rel":5377},"https://medium.com/@dev.davexoyinbo/error-handling-in-rust-where-bugs-go-to-take-a-vacation-294683a5fd90",[35],[3198,5379,5380],{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}",{"title":231,"searchDepth":232,"depth":232,"links":5382},[5383,5384,5388,5392,5393,5394],{"id":286,"depth":232,"text":287},{"id":3562,"depth":232,"text":3563,"children":5385},[5386,5387],{"id":3566,"depth":385,"text":3567},{"id":3901,"depth":385,"text":3902},{"id":4317,"depth":232,"text":4318,"children":5389},[5390,5391],{"id":4353,"depth":385,"text":4354},{"id":4631,"depth":385,"text":4632},{"id":4900,"depth":232,"text":4901},{"id":5234,"depth":232,"text":5235},{"id":3165,"depth":232,"text":3166},"2024-02-02T00:00:00.000Z","Safeguarding Software Reliability with Rust's Error Handling Mechanisms - exploring Result and Option enums, the ? operator, custom error types, and panic! for robust error management",{},"/engineering-logs/error-handling-rust","6 min",{"title":3526,"description":5396},"engineering-logs/error-handling-rust",[249,5403,3225,5404,2446,5405],"error-handling","software-development","option","pU1czJBN406B6iyAHKuzHR6PgdgNtWvBUiFxGMn2Wo4",1784683929112]