[{"data":1,"prerenderedAt":4595},["ShallowReactive",2],{"page-\u002Frust\u002F30-design-patterns":3},{"id":4,"title":5,"body":6,"description":16,"extension":4589,"meta":4590,"navigation":123,"path":4591,"seo":4592,"stem":4593,"__hash__":4594},"content\u002Frust\u002F30-design-patterns.md","30 — Design Patterns & Idiomatic Rust",{"type":7,"value":8,"toc":4546},"minimark",[9,13,17,22,25,749,760,765,965,979,983,1135,1162,1166,1169,1467,1477,1481,1804,1810,1814,1817,2108,2115,2119,2409,2413,2420,2602,2605,2609,2612,2732,2745,2749,2850,2853,2857,2860,2973,2981,2985,3061,3071,3147,3156,3167,3275,3281,3354,3367,3371,3439,3442,3446,3527,3531,3626,3629,3633,3642,3646,3649,3653,3821,3832,3836,3847,3854,3864,3868,3977,3980,3988,4004,4008,4101,4131,4135,4170,4174,4187,4191,4202,4210,4335,4338,4342,4348,4352,4444,4448,4516,4520,4539,4542],[10,11,5],"h1",{"id":12},"_30-design-patterns-idiomatic-rust",[14,15,16],"p",{},"Rust isn't OOP, but it has idioms for abstraction, polymorphism, and reuse. Here are the patterns every pro Rust developer should know.",[18,19,21],"h2",{"id":20},"_1-builder-pattern","1. Builder Pattern",[14,23,24],{},"For complex construction with many optional parameters:",[26,27,29],"code-wrapper",{"language":28},"rust",[30,31,35],"pre",{"className":32,"code":33,"language":28,"meta":34,"style":34},"language-rust shiki shiki-themes github-light github-dark","pub struct Server {\n    host: String,\n    port: u16,\n    tls: bool,\n    max_conn: usize,\n}\n\npub struct ServerBuilder {\n    host: Option\u003CString>,\n    port: Option\u003Cu16>,\n    tls: Option\u003Cbool>,\n    max_conn: Option\u003Cusize>,\n}\n\nimpl ServerBuilder {\n    pub fn new() -> Self {\n        ServerBuilder { host: None, port: None, tls: None, max_conn: None }\n    }\n    pub fn host(mut self, host: impl Into\u003CString>) -> Self { self.host = Some(host.into()); self }\n    pub fn port(mut self, port: u16) -> Self { self.port = Some(port); self }\n    pub fn tls(mut self, tls: bool) -> Self { self.tls = Some(tls); self }\n    pub fn max_conn(mut self, m: usize) -> Self { self.max_conn = Some(m); self }\n    pub fn build(self) -> Result\u003CServer, String> {\n        Ok(Server {\n            host: self.host.ok_or(\"host required\")?,\n            port: self.port.unwrap_or(80),\n            tls: self.tls.unwrap_or(false),\n            max_conn: self.max_conn.unwrap_or(100),\n        })\n    }\n}\n\nlet s = ServerBuilder::new().host(\"localhost\").tls(true).build()?;\n","",[36,37,38,58,73,86,99,112,118,125,137,156,172,188,204,209,214,224,248,286,292,366,415,463,512,546,558,592,620,646,672,678,683,688,693],"code",{"__ignoreMap":34},[39,40,43,47,50,54],"span",{"class":41,"line":42},"line",1,[39,44,46],{"class":45},"svdQ7","pub",[39,48,49],{"class":45}," struct",[39,51,53],{"class":52},"sIsaT"," Server",[39,55,57],{"class":56},"ssxIu"," {\n",[39,59,61,64,67,70],{"class":41,"line":60},2,[39,62,63],{"class":56},"    host",[39,65,66],{"class":45},":",[39,68,69],{"class":52}," String",[39,71,72],{"class":56},",\n",[39,74,76,79,81,84],{"class":41,"line":75},3,[39,77,78],{"class":56},"    port",[39,80,66],{"class":45},[39,82,83],{"class":52}," u16",[39,85,72],{"class":56},[39,87,89,92,94,97],{"class":41,"line":88},4,[39,90,91],{"class":56},"    tls",[39,93,66],{"class":45},[39,95,96],{"class":52}," bool",[39,98,72],{"class":56},[39,100,102,105,107,110],{"class":41,"line":101},5,[39,103,104],{"class":56},"    max_conn",[39,106,66],{"class":45},[39,108,109],{"class":52}," usize",[39,111,72],{"class":56},[39,113,115],{"class":41,"line":114},6,[39,116,117],{"class":56},"}\n",[39,119,121],{"class":41,"line":120},7,[39,122,124],{"emptyLinePlaceholder":123},true,"\n",[39,126,128,130,132,135],{"class":41,"line":127},8,[39,129,46],{"class":45},[39,131,49],{"class":45},[39,133,134],{"class":52}," ServerBuilder",[39,136,57],{"class":56},[39,138,140,142,144,147,150,153],{"class":41,"line":139},9,[39,141,63],{"class":56},[39,143,66],{"class":45},[39,145,146],{"class":52}," Option",[39,148,149],{"class":56},"\u003C",[39,151,152],{"class":52},"String",[39,154,155],{"class":56},">,\n",[39,157,159,161,163,165,167,170],{"class":41,"line":158},10,[39,160,78],{"class":56},[39,162,66],{"class":45},[39,164,146],{"class":52},[39,166,149],{"class":56},[39,168,169],{"class":52},"u16",[39,171,155],{"class":56},[39,173,175,177,179,181,183,186],{"class":41,"line":174},11,[39,176,91],{"class":56},[39,178,66],{"class":45},[39,180,146],{"class":52},[39,182,149],{"class":56},[39,184,185],{"class":52},"bool",[39,187,155],{"class":56},[39,189,191,193,195,197,199,202],{"class":41,"line":190},12,[39,192,104],{"class":56},[39,194,66],{"class":45},[39,196,146],{"class":52},[39,198,149],{"class":56},[39,200,201],{"class":52},"usize",[39,203,155],{"class":56},[39,205,207],{"class":41,"line":206},13,[39,208,117],{"class":56},[39,210,212],{"class":41,"line":211},14,[39,213,124],{"emptyLinePlaceholder":123},[39,215,217,220,222],{"class":41,"line":216},15,[39,218,219],{"class":45},"impl",[39,221,134],{"class":52},[39,223,57],{"class":56},[39,225,227,230,233,236,239,242,246],{"class":41,"line":226},16,[39,228,229],{"class":45},"    pub",[39,231,232],{"class":45}," fn",[39,234,235],{"class":52}," new",[39,237,238],{"class":56},"() ",[39,240,241],{"class":45},"->",[39,243,245],{"class":244},"snvgF"," Self",[39,247,57],{"class":56},[39,249,251,254,257,259,262,265,267,269,272,274,276,279,281,283],{"class":41,"line":250},17,[39,252,253],{"class":52},"        ServerBuilder",[39,255,256],{"class":56}," { host",[39,258,66],{"class":45},[39,260,261],{"class":52}," None",[39,263,264],{"class":56},", port",[39,266,66],{"class":45},[39,268,261],{"class":52},[39,270,271],{"class":56},", tls",[39,273,66],{"class":45},[39,275,261],{"class":52},[39,277,278],{"class":56},", max_conn",[39,280,66],{"class":45},[39,282,261],{"class":52},[39,284,285],{"class":56}," }\n",[39,287,289],{"class":41,"line":288},18,[39,290,291],{"class":56},"    }\n",[39,293,295,297,299,302,305,308,311,314,316,319,322,324,326,329,331,333,336,339,342,345,348,351,354,356,359,362,364],{"class":41,"line":294},19,[39,296,229],{"class":45},[39,298,232],{"class":45},[39,300,301],{"class":52}," host",[39,303,304],{"class":56},"(",[39,306,307],{"class":45},"mut",[39,309,310],{"class":244}," self",[39,312,313],{"class":56},", host",[39,315,66],{"class":45},[39,317,318],{"class":45}," impl",[39,320,321],{"class":52}," Into",[39,323,149],{"class":56},[39,325,152],{"class":52},[39,327,328],{"class":56},">) ",[39,330,241],{"class":45},[39,332,245],{"class":244},[39,334,335],{"class":56}," { ",[39,337,338],{"class":244},"self",[39,340,341],{"class":45},".",[39,343,344],{"class":56},"host ",[39,346,347],{"class":45},"=",[39,349,350],{"class":52}," Some",[39,352,353],{"class":56},"(host",[39,355,341],{"class":45},[39,357,358],{"class":52},"into",[39,360,361],{"class":56},"()); ",[39,363,338],{"class":244},[39,365,285],{"class":56},[39,367,369,371,373,376,378,380,382,384,386,388,391,393,395,397,399,401,404,406,408,411,413],{"class":41,"line":368},20,[39,370,229],{"class":45},[39,372,232],{"class":45},[39,374,375],{"class":52}," port",[39,377,304],{"class":56},[39,379,307],{"class":45},[39,381,310],{"class":244},[39,383,264],{"class":56},[39,385,66],{"class":45},[39,387,83],{"class":52},[39,389,390],{"class":56},") ",[39,392,241],{"class":45},[39,394,245],{"class":244},[39,396,335],{"class":56},[39,398,338],{"class":244},[39,400,341],{"class":45},[39,402,403],{"class":56},"port ",[39,405,347],{"class":45},[39,407,350],{"class":52},[39,409,410],{"class":56},"(port); ",[39,412,338],{"class":244},[39,414,285],{"class":56},[39,416,418,420,422,425,427,429,431,433,435,437,439,441,443,445,447,449,452,454,456,459,461],{"class":41,"line":417},21,[39,419,229],{"class":45},[39,421,232],{"class":45},[39,423,424],{"class":52}," tls",[39,426,304],{"class":56},[39,428,307],{"class":45},[39,430,310],{"class":244},[39,432,271],{"class":56},[39,434,66],{"class":45},[39,436,96],{"class":52},[39,438,390],{"class":56},[39,440,241],{"class":45},[39,442,245],{"class":244},[39,444,335],{"class":56},[39,446,338],{"class":244},[39,448,341],{"class":45},[39,450,451],{"class":56},"tls ",[39,453,347],{"class":45},[39,455,350],{"class":52},[39,457,458],{"class":56},"(tls); ",[39,460,338],{"class":244},[39,462,285],{"class":56},[39,464,466,468,470,473,475,477,479,482,484,486,488,490,492,494,496,498,501,503,505,508,510],{"class":41,"line":465},22,[39,467,229],{"class":45},[39,469,232],{"class":45},[39,471,472],{"class":52}," max_conn",[39,474,304],{"class":56},[39,476,307],{"class":45},[39,478,310],{"class":244},[39,480,481],{"class":56},", m",[39,483,66],{"class":45},[39,485,109],{"class":52},[39,487,390],{"class":56},[39,489,241],{"class":45},[39,491,245],{"class":244},[39,493,335],{"class":56},[39,495,338],{"class":244},[39,497,341],{"class":45},[39,499,500],{"class":56},"max_conn ",[39,502,347],{"class":45},[39,504,350],{"class":52},[39,506,507],{"class":56},"(m); ",[39,509,338],{"class":244},[39,511,285],{"class":56},[39,513,515,517,519,522,524,526,528,530,533,535,538,541,543],{"class":41,"line":514},23,[39,516,229],{"class":45},[39,518,232],{"class":45},[39,520,521],{"class":52}," build",[39,523,304],{"class":56},[39,525,338],{"class":244},[39,527,390],{"class":56},[39,529,241],{"class":45},[39,531,532],{"class":52}," Result",[39,534,149],{"class":56},[39,536,537],{"class":52},"Server",[39,539,540],{"class":56},", ",[39,542,152],{"class":52},[39,544,545],{"class":56},"> {\n",[39,547,549,552,554,556],{"class":41,"line":548},24,[39,550,551],{"class":52},"        Ok",[39,553,304],{"class":56},[39,555,537],{"class":52},[39,557,57],{"class":56},[39,559,561,564,566,568,570,573,575,578,580,584,587,590],{"class":41,"line":560},25,[39,562,563],{"class":56},"            host",[39,565,66],{"class":45},[39,567,310],{"class":244},[39,569,341],{"class":45},[39,571,572],{"class":56},"host",[39,574,341],{"class":45},[39,576,577],{"class":52},"ok_or",[39,579,304],{"class":56},[39,581,583],{"class":582},"sJ6F3","\"host required\"",[39,585,586],{"class":56},")",[39,588,589],{"class":45},"?",[39,591,72],{"class":56},[39,593,595,598,600,602,604,607,609,612,614,617],{"class":41,"line":594},26,[39,596,597],{"class":56},"            port",[39,599,66],{"class":45},[39,601,310],{"class":244},[39,603,341],{"class":45},[39,605,606],{"class":56},"port",[39,608,341],{"class":45},[39,610,611],{"class":52},"unwrap_or",[39,613,304],{"class":56},[39,615,616],{"class":244},"80",[39,618,619],{"class":56},"),\n",[39,621,623,626,628,630,632,635,637,639,641,644],{"class":41,"line":622},27,[39,624,625],{"class":56},"            tls",[39,627,66],{"class":45},[39,629,310],{"class":244},[39,631,341],{"class":45},[39,633,634],{"class":56},"tls",[39,636,341],{"class":45},[39,638,611],{"class":52},[39,640,304],{"class":56},[39,642,643],{"class":244},"false",[39,645,619],{"class":56},[39,647,649,652,654,656,658,661,663,665,667,670],{"class":41,"line":648},28,[39,650,651],{"class":56},"            max_conn",[39,653,66],{"class":45},[39,655,310],{"class":244},[39,657,341],{"class":45},[39,659,660],{"class":56},"max_conn",[39,662,341],{"class":45},[39,664,611],{"class":52},[39,666,304],{"class":56},[39,668,669],{"class":244},"100",[39,671,619],{"class":56},[39,673,675],{"class":41,"line":674},29,[39,676,677],{"class":56},"        })\n",[39,679,681],{"class":41,"line":680},30,[39,682,291],{"class":56},[39,684,686],{"class":41,"line":685},31,[39,687,117],{"class":56},[39,689,691],{"class":41,"line":690},32,[39,692,124],{"emptyLinePlaceholder":123},[39,694,696,699,702,704,706,709,712,715,717,719,721,724,726,728,730,732,735,737,739,742,744,746],{"class":41,"line":695},33,[39,697,698],{"class":45},"let",[39,700,701],{"class":56}," s ",[39,703,347],{"class":45},[39,705,134],{"class":52},[39,707,708],{"class":45},"::",[39,710,711],{"class":52},"new",[39,713,714],{"class":56},"()",[39,716,341],{"class":45},[39,718,572],{"class":52},[39,720,304],{"class":56},[39,722,723],{"class":582},"\"localhost\"",[39,725,586],{"class":56},[39,727,341],{"class":45},[39,729,634],{"class":52},[39,731,304],{"class":56},[39,733,734],{"class":244},"true",[39,736,586],{"class":56},[39,738,341],{"class":45},[39,740,741],{"class":52},"build",[39,743,714],{"class":56},[39,745,589],{"class":45},[39,747,748],{"class":56},";\n",[14,750,751,752,755,756,759],{},"For less boilerplate, use the ",[36,753,754],{},"derive_builder"," or ",[36,757,758],{},"typed_builder"," crates.",[761,762,764],"h3",{"id":763},"typestate-builder","Typestate Builder",[26,766,767],{"language":28},[30,768,770],{"className":32,"code":769,"language":28,"meta":34,"style":34},"pub struct MissingHost;\npub struct WithHost(String);\n\npub struct ServerBuilder\u003CH> { host: H, \u002F* ... *\u002F }\n\nimpl ServerBuilder\u003CMissingHost> {\n    pub fn new() -> Self { ServerBuilder { host: MissingHost } }\n    pub fn host(self, h: String) -> ServerBuilder\u003CWithHost> { ServerBuilder { host: WithHost(h) } }\n}\nimpl ServerBuilder\u003CWithHost> {\n    pub fn build(self) -> Server { \u002F* ... *\u002F }\n}\n",[36,771,772,783,799,803,832,836,849,877,921,925,937,961],{"__ignoreMap":34},[39,773,774,776,778,781],{"class":41,"line":42},[39,775,46],{"class":45},[39,777,49],{"class":45},[39,779,780],{"class":52}," MissingHost",[39,782,748],{"class":56},[39,784,785,787,789,792,794,796],{"class":41,"line":60},[39,786,46],{"class":45},[39,788,49],{"class":45},[39,790,791],{"class":52}," WithHost",[39,793,304],{"class":56},[39,795,152],{"class":52},[39,797,798],{"class":56},");\n",[39,800,801],{"class":41,"line":75},[39,802,124],{"emptyLinePlaceholder":123},[39,804,805,807,809,811,813,816,819,821,824,826,830],{"class":41,"line":88},[39,806,46],{"class":45},[39,808,49],{"class":45},[39,810,134],{"class":52},[39,812,149],{"class":56},[39,814,815],{"class":52},"H",[39,817,818],{"class":56},"> { host",[39,820,66],{"class":45},[39,822,823],{"class":52}," H",[39,825,540],{"class":56},[39,827,829],{"class":828},"sdCPZ","\u002F* ... *\u002F",[39,831,285],{"class":56},[39,833,834],{"class":41,"line":101},[39,835,124],{"emptyLinePlaceholder":123},[39,837,838,840,842,844,847],{"class":41,"line":114},[39,839,219],{"class":45},[39,841,134],{"class":52},[39,843,149],{"class":56},[39,845,846],{"class":52},"MissingHost",[39,848,545],{"class":56},[39,850,851,853,855,857,859,861,863,865,868,870,872,874],{"class":41,"line":120},[39,852,229],{"class":45},[39,854,232],{"class":45},[39,856,235],{"class":52},[39,858,238],{"class":56},[39,860,241],{"class":45},[39,862,245],{"class":244},[39,864,335],{"class":56},[39,866,867],{"class":52},"ServerBuilder",[39,869,256],{"class":56},[39,871,66],{"class":45},[39,873,780],{"class":52},[39,875,876],{"class":56}," } }\n",[39,878,879,881,883,885,887,889,892,894,896,898,900,902,904,907,910,912,914,916,918],{"class":41,"line":127},[39,880,229],{"class":45},[39,882,232],{"class":45},[39,884,301],{"class":52},[39,886,304],{"class":56},[39,888,338],{"class":244},[39,890,891],{"class":56},", h",[39,893,66],{"class":45},[39,895,69],{"class":52},[39,897,390],{"class":56},[39,899,241],{"class":45},[39,901,134],{"class":52},[39,903,149],{"class":56},[39,905,906],{"class":52},"WithHost",[39,908,909],{"class":56},"> { ",[39,911,867],{"class":52},[39,913,256],{"class":56},[39,915,66],{"class":45},[39,917,791],{"class":52},[39,919,920],{"class":56},"(h) } }\n",[39,922,923],{"class":41,"line":139},[39,924,117],{"class":56},[39,926,927,929,931,933,935],{"class":41,"line":158},[39,928,219],{"class":45},[39,930,134],{"class":52},[39,932,149],{"class":56},[39,934,906],{"class":52},[39,936,545],{"class":56},[39,938,939,941,943,945,947,949,951,953,955,957,959],{"class":41,"line":174},[39,940,229],{"class":45},[39,942,232],{"class":45},[39,944,521],{"class":52},[39,946,304],{"class":56},[39,948,338],{"class":244},[39,950,390],{"class":56},[39,952,241],{"class":45},[39,954,53],{"class":52},[39,956,335],{"class":56},[39,958,829],{"class":828},[39,960,285],{"class":56},[39,962,963],{"class":41,"line":190},[39,964,117],{"class":56},[14,966,967,968,971,972,974,975,978],{},"Compile-time enforcement: you can't ",[36,969,970],{},"build()"," without setting ",[36,973,572],{},". The ",[36,976,977],{},"bon"," crate provides this ergonomically.",[18,980,982],{"id":981},"_2-newtype-pattern","2. Newtype Pattern",[26,984,985],{"language":28},[30,986,988],{"className":32,"code":987,"language":28,"meta":34,"style":34},"pub struct UserId(pub u64);\npub struct Email(pub String);\n\nimpl Email {\n    pub fn new(s: String) -> Result\u003CSelf, &'static str> {\n        if s.contains('@') { Ok(Email(s)) } else { Err(\"invalid\") }\n    }\n}\n",[36,989,990,1008,1025,1029,1037,1079,1127,1131],{"__ignoreMap":34},[39,991,992,994,996,999,1001,1003,1006],{"class":41,"line":42},[39,993,46],{"class":45},[39,995,49],{"class":45},[39,997,998],{"class":52}," UserId",[39,1000,304],{"class":56},[39,1002,46],{"class":45},[39,1004,1005],{"class":52}," u64",[39,1007,798],{"class":56},[39,1009,1010,1012,1014,1017,1019,1021,1023],{"class":41,"line":60},[39,1011,46],{"class":45},[39,1013,49],{"class":45},[39,1015,1016],{"class":52}," Email",[39,1018,304],{"class":56},[39,1020,46],{"class":45},[39,1022,69],{"class":52},[39,1024,798],{"class":56},[39,1026,1027],{"class":41,"line":75},[39,1028,124],{"emptyLinePlaceholder":123},[39,1030,1031,1033,1035],{"class":41,"line":88},[39,1032,219],{"class":45},[39,1034,1016],{"class":52},[39,1036,57],{"class":56},[39,1038,1039,1041,1043,1045,1048,1050,1052,1054,1056,1058,1060,1063,1065,1068,1071,1074,1077],{"class":41,"line":101},[39,1040,229],{"class":45},[39,1042,232],{"class":45},[39,1044,235],{"class":52},[39,1046,1047],{"class":56},"(s",[39,1049,66],{"class":45},[39,1051,69],{"class":52},[39,1053,390],{"class":56},[39,1055,241],{"class":45},[39,1057,532],{"class":52},[39,1059,149],{"class":56},[39,1061,1062],{"class":244},"Self",[39,1064,540],{"class":56},[39,1066,1067],{"class":45},"&",[39,1069,1070],{"class":56},"'",[39,1072,1073],{"class":52},"static",[39,1075,1076],{"class":52}," str",[39,1078,545],{"class":56},[39,1080,1081,1084,1087,1089,1092,1094,1097,1100,1103,1105,1108,1111,1114,1116,1119,1121,1124],{"class":41,"line":114},[39,1082,1083],{"class":45},"        if",[39,1085,1086],{"class":56}," s",[39,1088,341],{"class":45},[39,1090,1091],{"class":52},"contains",[39,1093,304],{"class":56},[39,1095,1096],{"class":582},"'@'",[39,1098,1099],{"class":56},") { ",[39,1101,1102],{"class":52},"Ok",[39,1104,304],{"class":56},[39,1106,1107],{"class":52},"Email",[39,1109,1110],{"class":56},"(s)) } ",[39,1112,1113],{"class":45},"else",[39,1115,335],{"class":56},[39,1117,1118],{"class":52},"Err",[39,1120,304],{"class":56},[39,1122,1123],{"class":582},"\"invalid\"",[39,1125,1126],{"class":56},") }\n",[39,1128,1129],{"class":41,"line":120},[39,1130,291],{"class":56},[39,1132,1133],{"class":41,"line":127},[39,1134,117],{"class":56},[1136,1137,1138,1142,1145],"ul",{},[1139,1140,1141],"li",{},"Zero-cost type distinction.",[1139,1143,1144],{},"Constructor can validate invariants.",[1139,1146,1147,1148,1151,1152,1151,1155,1151,1158,1161],{},"Implement ",[36,1149,1150],{},"From","\u002F",[36,1153,1154],{},"Display",[36,1156,1157],{},"Debug",[36,1159,1160],{},"Deref"," as appropriate (don't over-implement).",[18,1163,1165],{"id":1164},"_3-typestate-pattern","3. Typestate Pattern",[14,1167,1168],{},"Encode state machines in types:",[26,1170,1171],{"language":28},[30,1172,1174],{"className":32,"code":1173,"language":28,"meta":34,"style":34},"pub struct Draft; pub struct Reviewed; pub struct Published;\n\npub struct Article\u003CS> { content: String, _state: PhantomData\u003CS> }\n\nimpl Article\u003CDraft> {\n    pub fn new(content: String) -> Self { Article { content, _state: PhantomData } }\n    pub fn review(self) -> Article\u003CReviewed> { Article { content: self.content, _state: PhantomData } }\n}\nimpl Article\u003CReviewed> {\n    pub fn publish(self) -> Article\u003CPublished> { Article { content: self.content, _state: PhantomData } }\n}\nimpl\u003CS> Article\u003CS> {\n    pub fn content(&self) -> &str { &self.content }\n}\n",[36,1175,1176,1206,1210,1246,1250,1263,1298,1344,1348,1360,1404,1408,1427,1463],{"__ignoreMap":34},[39,1177,1178,1180,1182,1185,1188,1190,1192,1195,1197,1199,1201,1204],{"class":41,"line":42},[39,1179,46],{"class":45},[39,1181,49],{"class":45},[39,1183,1184],{"class":52}," Draft",[39,1186,1187],{"class":56},"; ",[39,1189,46],{"class":45},[39,1191,49],{"class":45},[39,1193,1194],{"class":52}," Reviewed",[39,1196,1187],{"class":56},[39,1198,46],{"class":45},[39,1200,49],{"class":45},[39,1202,1203],{"class":52}," Published",[39,1205,748],{"class":56},[39,1207,1208],{"class":41,"line":60},[39,1209,124],{"emptyLinePlaceholder":123},[39,1211,1212,1214,1216,1219,1221,1224,1227,1229,1231,1234,1236,1239,1241,1243],{"class":41,"line":75},[39,1213,46],{"class":45},[39,1215,49],{"class":45},[39,1217,1218],{"class":52}," Article",[39,1220,149],{"class":56},[39,1222,1223],{"class":52},"S",[39,1225,1226],{"class":56},"> { content",[39,1228,66],{"class":45},[39,1230,69],{"class":52},[39,1232,1233],{"class":56},", _state",[39,1235,66],{"class":45},[39,1237,1238],{"class":52}," PhantomData",[39,1240,149],{"class":56},[39,1242,1223],{"class":52},[39,1244,1245],{"class":56},"> }\n",[39,1247,1248],{"class":41,"line":88},[39,1249,124],{"emptyLinePlaceholder":123},[39,1251,1252,1254,1256,1258,1261],{"class":41,"line":101},[39,1253,219],{"class":45},[39,1255,1218],{"class":52},[39,1257,149],{"class":56},[39,1259,1260],{"class":52},"Draft",[39,1262,545],{"class":56},[39,1264,1265,1267,1269,1271,1274,1276,1278,1280,1282,1284,1286,1289,1292,1294,1296],{"class":41,"line":114},[39,1266,229],{"class":45},[39,1268,232],{"class":45},[39,1270,235],{"class":52},[39,1272,1273],{"class":56},"(content",[39,1275,66],{"class":45},[39,1277,69],{"class":52},[39,1279,390],{"class":56},[39,1281,241],{"class":45},[39,1283,245],{"class":244},[39,1285,335],{"class":56},[39,1287,1288],{"class":52},"Article",[39,1290,1291],{"class":56}," { content, _state",[39,1293,66],{"class":45},[39,1295,1238],{"class":52},[39,1297,876],{"class":56},[39,1299,1300,1302,1304,1307,1309,1311,1313,1315,1317,1319,1322,1324,1326,1329,1331,1333,1335,1338,1340,1342],{"class":41,"line":120},[39,1301,229],{"class":45},[39,1303,232],{"class":45},[39,1305,1306],{"class":52}," review",[39,1308,304],{"class":56},[39,1310,338],{"class":244},[39,1312,390],{"class":56},[39,1314,241],{"class":45},[39,1316,1218],{"class":52},[39,1318,149],{"class":56},[39,1320,1321],{"class":52},"Reviewed",[39,1323,909],{"class":56},[39,1325,1288],{"class":52},[39,1327,1328],{"class":56}," { content",[39,1330,66],{"class":45},[39,1332,310],{"class":244},[39,1334,341],{"class":45},[39,1336,1337],{"class":56},"content, _state",[39,1339,66],{"class":45},[39,1341,1238],{"class":52},[39,1343,876],{"class":56},[39,1345,1346],{"class":41,"line":127},[39,1347,117],{"class":56},[39,1349,1350,1352,1354,1356,1358],{"class":41,"line":139},[39,1351,219],{"class":45},[39,1353,1218],{"class":52},[39,1355,149],{"class":56},[39,1357,1321],{"class":52},[39,1359,545],{"class":56},[39,1361,1362,1364,1366,1369,1371,1373,1375,1377,1379,1381,1384,1386,1388,1390,1392,1394,1396,1398,1400,1402],{"class":41,"line":158},[39,1363,229],{"class":45},[39,1365,232],{"class":45},[39,1367,1368],{"class":52}," publish",[39,1370,304],{"class":56},[39,1372,338],{"class":244},[39,1374,390],{"class":56},[39,1376,241],{"class":45},[39,1378,1218],{"class":52},[39,1380,149],{"class":56},[39,1382,1383],{"class":52},"Published",[39,1385,909],{"class":56},[39,1387,1288],{"class":52},[39,1389,1328],{"class":56},[39,1391,66],{"class":45},[39,1393,310],{"class":244},[39,1395,341],{"class":45},[39,1397,1337],{"class":56},[39,1399,66],{"class":45},[39,1401,1238],{"class":52},[39,1403,876],{"class":56},[39,1405,1406],{"class":41,"line":174},[39,1407,117],{"class":56},[39,1409,1410,1412,1414,1416,1419,1421,1423,1425],{"class":41,"line":190},[39,1411,219],{"class":45},[39,1413,149],{"class":56},[39,1415,1223],{"class":52},[39,1417,1418],{"class":56},"> ",[39,1420,1288],{"class":52},[39,1422,149],{"class":56},[39,1424,1223],{"class":52},[39,1426,545],{"class":56},[39,1428,1429,1431,1433,1436,1438,1440,1442,1444,1446,1449,1452,1454,1456,1458,1460],{"class":41,"line":206},[39,1430,229],{"class":45},[39,1432,232],{"class":45},[39,1434,1435],{"class":52}," content",[39,1437,304],{"class":56},[39,1439,1067],{"class":45},[39,1441,338],{"class":244},[39,1443,390],{"class":56},[39,1445,241],{"class":45},[39,1447,1448],{"class":45}," &",[39,1450,1451],{"class":52},"str",[39,1453,335],{"class":56},[39,1455,1067],{"class":45},[39,1457,338],{"class":244},[39,1459,341],{"class":45},[39,1461,1462],{"class":56},"content }\n",[39,1464,1465],{"class":41,"line":211},[39,1466,117],{"class":56},[14,1468,1469,1470,1473,1474,1476],{},"Calling ",[36,1471,1472],{},"publish"," on ",[36,1475,1260],{}," is a compile-time error. Methods only exist in valid states.",[18,1478,1480],{"id":1479},"_4-strategy-via-traits","4. Strategy via Traits",[26,1482,1483],{"language":28},[30,1484,1486],{"className":32,"code":1485,"language":28,"meta":34,"style":34},"pub trait Compressor { fn compress(&self, data: &[u8]) -> Vec\u003Cu8>; }\n\npub struct Gzip; pub struct Lz4;\n\nimpl Compressor for Gzip { fn compress(&self, data: &[u8]) -> Vec\u003Cu8> { \u002F* ... *\u002F Vec::new() } }\nimpl Compressor for Lz4  { fn compress(&self, data: &[u8]) -> Vec\u003Cu8> { \u002F* ... *\u002F Vec::new() } }\n\npub fn archive\u003CC: Compressor>(compressor: &C, files: &[File]) -> Vec\u003Cu8> {\n    let mut out = Vec::new();\n    for f in files { out.extend(compressor.compress(&f.data)); }\n    out\n}\n",[36,1487,1488,1540,1544,1564,1568,1624,1679,1683,1734,1756,1795,1800],{"__ignoreMap":34},[39,1489,1490,1492,1495,1498,1500,1503,1506,1508,1510,1512,1515,1517,1519,1522,1525,1528,1530,1533,1535,1537],{"class":41,"line":42},[39,1491,46],{"class":45},[39,1493,1494],{"class":45}," trait",[39,1496,1497],{"class":52}," Compressor",[39,1499,335],{"class":56},[39,1501,1502],{"class":45},"fn",[39,1504,1505],{"class":52}," compress",[39,1507,304],{"class":56},[39,1509,1067],{"class":45},[39,1511,338],{"class":244},[39,1513,1514],{"class":56},", data",[39,1516,66],{"class":45},[39,1518,1448],{"class":45},[39,1520,1521],{"class":56},"[",[39,1523,1524],{"class":52},"u8",[39,1526,1527],{"class":56},"]) ",[39,1529,241],{"class":45},[39,1531,1532],{"class":52}," Vec",[39,1534,149],{"class":56},[39,1536,1524],{"class":52},[39,1538,1539],{"class":56},">; }\n",[39,1541,1542],{"class":41,"line":60},[39,1543,124],{"emptyLinePlaceholder":123},[39,1545,1546,1548,1550,1553,1555,1557,1559,1562],{"class":41,"line":75},[39,1547,46],{"class":45},[39,1549,49],{"class":45},[39,1551,1552],{"class":52}," Gzip",[39,1554,1187],{"class":56},[39,1556,46],{"class":45},[39,1558,49],{"class":45},[39,1560,1561],{"class":52}," Lz4",[39,1563,748],{"class":56},[39,1565,1566],{"class":41,"line":88},[39,1567,124],{"emptyLinePlaceholder":123},[39,1569,1570,1572,1574,1577,1579,1581,1583,1585,1587,1589,1591,1593,1595,1597,1599,1601,1603,1605,1607,1609,1611,1613,1615,1617,1619,1621],{"class":41,"line":101},[39,1571,219],{"class":45},[39,1573,1497],{"class":52},[39,1575,1576],{"class":45}," for",[39,1578,1552],{"class":52},[39,1580,335],{"class":56},[39,1582,1502],{"class":45},[39,1584,1505],{"class":52},[39,1586,304],{"class":56},[39,1588,1067],{"class":45},[39,1590,338],{"class":244},[39,1592,1514],{"class":56},[39,1594,66],{"class":45},[39,1596,1448],{"class":45},[39,1598,1521],{"class":56},[39,1600,1524],{"class":52},[39,1602,1527],{"class":56},[39,1604,241],{"class":45},[39,1606,1532],{"class":52},[39,1608,149],{"class":56},[39,1610,1524],{"class":52},[39,1612,909],{"class":56},[39,1614,829],{"class":828},[39,1616,1532],{"class":52},[39,1618,708],{"class":45},[39,1620,711],{"class":52},[39,1622,1623],{"class":56},"() } }\n",[39,1625,1626,1628,1630,1632,1634,1637,1639,1641,1643,1645,1647,1649,1651,1653,1655,1657,1659,1661,1663,1665,1667,1669,1671,1673,1675,1677],{"class":41,"line":114},[39,1627,219],{"class":45},[39,1629,1497],{"class":52},[39,1631,1576],{"class":45},[39,1633,1561],{"class":52},[39,1635,1636],{"class":56},"  { ",[39,1638,1502],{"class":45},[39,1640,1505],{"class":52},[39,1642,304],{"class":56},[39,1644,1067],{"class":45},[39,1646,338],{"class":244},[39,1648,1514],{"class":56},[39,1650,66],{"class":45},[39,1652,1448],{"class":45},[39,1654,1521],{"class":56},[39,1656,1524],{"class":52},[39,1658,1527],{"class":56},[39,1660,241],{"class":45},[39,1662,1532],{"class":52},[39,1664,149],{"class":56},[39,1666,1524],{"class":52},[39,1668,909],{"class":56},[39,1670,829],{"class":828},[39,1672,1532],{"class":52},[39,1674,708],{"class":45},[39,1676,711],{"class":52},[39,1678,1623],{"class":56},[39,1680,1681],{"class":41,"line":120},[39,1682,124],{"emptyLinePlaceholder":123},[39,1684,1685,1687,1689,1692,1694,1697,1699,1701,1704,1706,1708,1710,1713,1715,1717,1719,1722,1724,1726,1728,1730,1732],{"class":41,"line":127},[39,1686,46],{"class":45},[39,1688,232],{"class":45},[39,1690,1691],{"class":52}," archive",[39,1693,149],{"class":56},[39,1695,1696],{"class":52},"C",[39,1698,66],{"class":45},[39,1700,1497],{"class":52},[39,1702,1703],{"class":56},">(compressor",[39,1705,66],{"class":45},[39,1707,1448],{"class":45},[39,1709,1696],{"class":52},[39,1711,1712],{"class":56},", files",[39,1714,66],{"class":45},[39,1716,1448],{"class":45},[39,1718,1521],{"class":56},[39,1720,1721],{"class":52},"File",[39,1723,1527],{"class":56},[39,1725,241],{"class":45},[39,1727,1532],{"class":52},[39,1729,149],{"class":56},[39,1731,1524],{"class":52},[39,1733,545],{"class":56},[39,1735,1736,1739,1742,1745,1747,1749,1751,1753],{"class":41,"line":139},[39,1737,1738],{"class":45},"    let",[39,1740,1741],{"class":45}," mut",[39,1743,1744],{"class":56}," out ",[39,1746,347],{"class":45},[39,1748,1532],{"class":52},[39,1750,708],{"class":45},[39,1752,711],{"class":52},[39,1754,1755],{"class":56},"();\n",[39,1757,1758,1761,1764,1767,1770,1772,1775,1778,1780,1783,1785,1787,1790,1792],{"class":41,"line":158},[39,1759,1760],{"class":45},"    for",[39,1762,1763],{"class":56}," f ",[39,1765,1766],{"class":45},"in",[39,1768,1769],{"class":56}," files { out",[39,1771,341],{"class":45},[39,1773,1774],{"class":52},"extend",[39,1776,1777],{"class":56},"(compressor",[39,1779,341],{"class":45},[39,1781,1782],{"class":52},"compress",[39,1784,304],{"class":56},[39,1786,1067],{"class":45},[39,1788,1789],{"class":56},"f",[39,1791,341],{"class":45},[39,1793,1794],{"class":56},"data)); }\n",[39,1796,1797],{"class":41,"line":174},[39,1798,1799],{"class":56},"    out\n",[39,1801,1802],{"class":41,"line":190},[39,1803,117],{"class":56},[14,1805,1806,1807,341],{},"Static dispatch via generics, or dynamic via ",[36,1808,1809],{},"Box\u003Cdyn Compressor>",[18,1811,1813],{"id":1812},"_5-visitor-pattern","5. Visitor Pattern",[14,1815,1816],{},"For traversing heterogeneous structures:",[26,1818,1819],{"language":28},[30,1820,1822],{"className":32,"code":1821,"language":28,"meta":34,"style":34},"pub trait Visitor {\n    fn visit_string(&mut self, s: &str);\n    fn visit_number(&mut self, n: f64);\n    fn visit_array(&mut self, elems: &[Value]);\n}\n\npub enum Value { Str(String), Num(f64), Arr(Vec\u003CValue>) }\n\nimpl Value {\n    pub fn accept(&self, v: &mut impl Visitor) {\n        match self {\n            Value::Str(s) => v.visit_string(s),\n            Value::Num(n) => v.visit_number(*n),\n            Value::Arr(a) => v.visit_array(a),\n        }\n    }\n}\n",[36,1823,1824,1835,1861,1884,1912,1916,1920,1967,1971,1979,2009,2018,2044,2072,2095,2100,2104],{"__ignoreMap":34},[39,1825,1826,1828,1830,1833],{"class":41,"line":42},[39,1827,46],{"class":45},[39,1829,1494],{"class":45},[39,1831,1832],{"class":52}," Visitor",[39,1834,57],{"class":56},[39,1836,1837,1840,1843,1845,1848,1850,1853,1855,1857,1859],{"class":41,"line":60},[39,1838,1839],{"class":45},"    fn",[39,1841,1842],{"class":52}," visit_string",[39,1844,304],{"class":56},[39,1846,1847],{"class":45},"&mut",[39,1849,310],{"class":244},[39,1851,1852],{"class":56},", s",[39,1854,66],{"class":45},[39,1856,1448],{"class":45},[39,1858,1451],{"class":52},[39,1860,798],{"class":56},[39,1862,1863,1865,1868,1870,1872,1874,1877,1879,1882],{"class":41,"line":75},[39,1864,1839],{"class":45},[39,1866,1867],{"class":52}," visit_number",[39,1869,304],{"class":56},[39,1871,1847],{"class":45},[39,1873,310],{"class":244},[39,1875,1876],{"class":56},", n",[39,1878,66],{"class":45},[39,1880,1881],{"class":52}," f64",[39,1883,798],{"class":56},[39,1885,1886,1888,1891,1893,1895,1897,1900,1902,1904,1906,1909],{"class":41,"line":88},[39,1887,1839],{"class":45},[39,1889,1890],{"class":52}," visit_array",[39,1892,304],{"class":56},[39,1894,1847],{"class":45},[39,1896,310],{"class":244},[39,1898,1899],{"class":56},", elems",[39,1901,66],{"class":45},[39,1903,1448],{"class":45},[39,1905,1521],{"class":56},[39,1907,1908],{"class":52},"Value",[39,1910,1911],{"class":56},"]);\n",[39,1913,1914],{"class":41,"line":101},[39,1915,117],{"class":56},[39,1917,1918],{"class":41,"line":114},[39,1919,124],{"emptyLinePlaceholder":123},[39,1921,1922,1924,1927,1930,1932,1935,1937,1939,1942,1945,1947,1950,1952,1955,1957,1960,1962,1964],{"class":41,"line":120},[39,1923,46],{"class":45},[39,1925,1926],{"class":45}," enum",[39,1928,1929],{"class":52}," Value",[39,1931,335],{"class":56},[39,1933,1934],{"class":52},"Str",[39,1936,304],{"class":56},[39,1938,152],{"class":52},[39,1940,1941],{"class":56},"), ",[39,1943,1944],{"class":52},"Num",[39,1946,304],{"class":56},[39,1948,1949],{"class":52},"f64",[39,1951,1941],{"class":56},[39,1953,1954],{"class":52},"Arr",[39,1956,304],{"class":56},[39,1958,1959],{"class":52},"Vec",[39,1961,149],{"class":56},[39,1963,1908],{"class":52},[39,1965,1966],{"class":56},">) }\n",[39,1968,1969],{"class":41,"line":127},[39,1970,124],{"emptyLinePlaceholder":123},[39,1972,1973,1975,1977],{"class":41,"line":139},[39,1974,219],{"class":45},[39,1976,1929],{"class":52},[39,1978,57],{"class":56},[39,1980,1981,1983,1985,1988,1990,1992,1994,1997,1999,2002,2004,2006],{"class":41,"line":158},[39,1982,229],{"class":45},[39,1984,232],{"class":45},[39,1986,1987],{"class":52}," accept",[39,1989,304],{"class":56},[39,1991,1067],{"class":45},[39,1993,338],{"class":244},[39,1995,1996],{"class":56},", v",[39,1998,66],{"class":45},[39,2000,2001],{"class":45}," &mut",[39,2003,318],{"class":45},[39,2005,1832],{"class":52},[39,2007,2008],{"class":56},") {\n",[39,2010,2011,2014,2016],{"class":41,"line":174},[39,2012,2013],{"class":45},"        match",[39,2015,310],{"class":244},[39,2017,57],{"class":56},[39,2019,2020,2023,2025,2027,2030,2033,2036,2038,2041],{"class":41,"line":190},[39,2021,2022],{"class":52},"            Value",[39,2024,708],{"class":45},[39,2026,1934],{"class":52},[39,2028,2029],{"class":56},"(s) ",[39,2031,2032],{"class":45},"=>",[39,2034,2035],{"class":56}," v",[39,2037,341],{"class":45},[39,2039,2040],{"class":52},"visit_string",[39,2042,2043],{"class":56},"(s),\n",[39,2045,2046,2048,2050,2052,2055,2057,2059,2061,2064,2066,2069],{"class":41,"line":206},[39,2047,2022],{"class":52},[39,2049,708],{"class":45},[39,2051,1944],{"class":52},[39,2053,2054],{"class":56},"(n) ",[39,2056,2032],{"class":45},[39,2058,2035],{"class":56},[39,2060,341],{"class":45},[39,2062,2063],{"class":52},"visit_number",[39,2065,304],{"class":56},[39,2067,2068],{"class":45},"*",[39,2070,2071],{"class":56},"n),\n",[39,2073,2074,2076,2078,2080,2083,2085,2087,2089,2092],{"class":41,"line":211},[39,2075,2022],{"class":52},[39,2077,708],{"class":45},[39,2079,1954],{"class":52},[39,2081,2082],{"class":56},"(a) ",[39,2084,2032],{"class":45},[39,2086,2035],{"class":56},[39,2088,341],{"class":45},[39,2090,2091],{"class":52},"visit_array",[39,2093,2094],{"class":56},"(a),\n",[39,2096,2097],{"class":41,"line":216},[39,2098,2099],{"class":56},"        }\n",[39,2101,2102],{"class":41,"line":226},[39,2103,291],{"class":56},[39,2105,2106],{"class":41,"line":250},[39,2107,117],{"class":56},[14,2109,2110,2111,2114],{},"Common in ",[36,2112,2113],{},"serde"," deserializers and AST traversal.",[18,2116,2118],{"id":2117},"_6-command-pattern","6. Command Pattern",[26,2120,2121],{"language":28},[30,2122,2124],{"className":32,"code":2123,"language":28,"meta":34,"style":34},"pub trait Command { fn execute(&self, ctx: &mut Context); }\n\npub struct Save { pub path: String }\nimpl Command for Save { fn execute(&self, ctx: &mut Context) { \u002F* ... *\u002F } }\n\npub struct Print { pub text: String }\nimpl Command for Print { fn execute(&self, ctx: &mut Context) { \u002F* ... *\u002F } }\n\nlet cmds: Vec\u003CBox\u003Cdyn Command>> = vec![\n    Box::new(Save { path: \"x\".into() }),\n    Box::new(Print { text: \"hi\".into() }),\n];\nfor c in cmds { c.execute(&mut ctx); }\n",[36,2125,2126,2161,2165,2187,2223,2227,2249,2285,2289,2323,2352,2379,2384],{"__ignoreMap":34},[39,2127,2128,2130,2132,2135,2137,2139,2142,2144,2146,2148,2151,2153,2155,2158],{"class":41,"line":42},[39,2129,46],{"class":45},[39,2131,1494],{"class":45},[39,2133,2134],{"class":52}," Command",[39,2136,335],{"class":56},[39,2138,1502],{"class":45},[39,2140,2141],{"class":52}," execute",[39,2143,304],{"class":56},[39,2145,1067],{"class":45},[39,2147,338],{"class":244},[39,2149,2150],{"class":56},", ctx",[39,2152,66],{"class":45},[39,2154,2001],{"class":45},[39,2156,2157],{"class":52}," Context",[39,2159,2160],{"class":56},"); }\n",[39,2162,2163],{"class":41,"line":60},[39,2164,124],{"emptyLinePlaceholder":123},[39,2166,2167,2169,2171,2174,2176,2178,2181,2183,2185],{"class":41,"line":75},[39,2168,46],{"class":45},[39,2170,49],{"class":45},[39,2172,2173],{"class":52}," Save",[39,2175,335],{"class":56},[39,2177,46],{"class":45},[39,2179,2180],{"class":56}," path",[39,2182,66],{"class":45},[39,2184,69],{"class":52},[39,2186,285],{"class":56},[39,2188,2189,2191,2193,2195,2197,2199,2201,2203,2205,2207,2209,2211,2213,2215,2217,2219,2221],{"class":41,"line":88},[39,2190,219],{"class":45},[39,2192,2134],{"class":52},[39,2194,1576],{"class":45},[39,2196,2173],{"class":52},[39,2198,335],{"class":56},[39,2200,1502],{"class":45},[39,2202,2141],{"class":52},[39,2204,304],{"class":56},[39,2206,1067],{"class":45},[39,2208,338],{"class":244},[39,2210,2150],{"class":56},[39,2212,66],{"class":45},[39,2214,2001],{"class":45},[39,2216,2157],{"class":52},[39,2218,1099],{"class":56},[39,2220,829],{"class":828},[39,2222,876],{"class":56},[39,2224,2225],{"class":41,"line":101},[39,2226,124],{"emptyLinePlaceholder":123},[39,2228,2229,2231,2233,2236,2238,2240,2243,2245,2247],{"class":41,"line":114},[39,2230,46],{"class":45},[39,2232,49],{"class":45},[39,2234,2235],{"class":52}," Print",[39,2237,335],{"class":56},[39,2239,46],{"class":45},[39,2241,2242],{"class":56}," text",[39,2244,66],{"class":45},[39,2246,69],{"class":52},[39,2248,285],{"class":56},[39,2250,2251,2253,2255,2257,2259,2261,2263,2265,2267,2269,2271,2273,2275,2277,2279,2281,2283],{"class":41,"line":120},[39,2252,219],{"class":45},[39,2254,2134],{"class":52},[39,2256,1576],{"class":45},[39,2258,2235],{"class":52},[39,2260,335],{"class":56},[39,2262,1502],{"class":45},[39,2264,2141],{"class":52},[39,2266,304],{"class":56},[39,2268,1067],{"class":45},[39,2270,338],{"class":244},[39,2272,2150],{"class":56},[39,2274,66],{"class":45},[39,2276,2001],{"class":45},[39,2278,2157],{"class":52},[39,2280,1099],{"class":56},[39,2282,829],{"class":828},[39,2284,876],{"class":56},[39,2286,2287],{"class":41,"line":127},[39,2288,124],{"emptyLinePlaceholder":123},[39,2290,2291,2293,2296,2298,2300,2302,2305,2307,2310,2312,2315,2317,2320],{"class":41,"line":139},[39,2292,698],{"class":45},[39,2294,2295],{"class":56}," cmds",[39,2297,66],{"class":45},[39,2299,1532],{"class":52},[39,2301,149],{"class":56},[39,2303,2304],{"class":52},"Box",[39,2306,149],{"class":56},[39,2308,2309],{"class":45},"dyn",[39,2311,2134],{"class":52},[39,2313,2314],{"class":56},">> ",[39,2316,347],{"class":45},[39,2318,2319],{"class":52}," vec!",[39,2321,2322],{"class":56},"[\n",[39,2324,2325,2328,2330,2332,2334,2337,2340,2342,2345,2347,2349],{"class":41,"line":158},[39,2326,2327],{"class":52},"    Box",[39,2329,708],{"class":45},[39,2331,711],{"class":52},[39,2333,304],{"class":56},[39,2335,2336],{"class":52},"Save",[39,2338,2339],{"class":56}," { path",[39,2341,66],{"class":45},[39,2343,2344],{"class":582}," \"x\"",[39,2346,341],{"class":45},[39,2348,358],{"class":52},[39,2350,2351],{"class":56},"() }),\n",[39,2353,2354,2356,2358,2360,2362,2365,2368,2370,2373,2375,2377],{"class":41,"line":174},[39,2355,2327],{"class":52},[39,2357,708],{"class":45},[39,2359,711],{"class":52},[39,2361,304],{"class":56},[39,2363,2364],{"class":52},"Print",[39,2366,2367],{"class":56}," { text",[39,2369,66],{"class":45},[39,2371,2372],{"class":582}," \"hi\"",[39,2374,341],{"class":45},[39,2376,358],{"class":52},[39,2378,2351],{"class":56},[39,2380,2381],{"class":41,"line":190},[39,2382,2383],{"class":56},"];\n",[39,2385,2386,2389,2392,2394,2397,2399,2402,2404,2406],{"class":41,"line":206},[39,2387,2388],{"class":45},"for",[39,2390,2391],{"class":56}," c ",[39,2393,1766],{"class":45},[39,2395,2396],{"class":56}," cmds { c",[39,2398,341],{"class":45},[39,2400,2401],{"class":52},"execute",[39,2403,304],{"class":56},[39,2405,1847],{"class":45},[39,2407,2408],{"class":56}," ctx); }\n",[18,2410,2412],{"id":2411},"_7-raii-resource-acquisition-is-initialization","7. RAII — Resource Acquisition Is Initialization",[14,2414,2415,2416,2419],{},"The most Rust-idiomatic pattern. Resources are tied to types; ",[36,2417,2418],{},"Drop"," cleans up:",[26,2421,2422],{"language":28},[30,2423,2425],{"className":32,"code":2424,"language":28,"meta":34,"style":34},"pub struct File { handle: RawFd }\nimpl File {\n    pub fn open(path: &str) -> std::io::Result\u003CSelf> {\n        let fd = unsafe { libc::open(...) };\n        Ok(File { handle: fd })\n    }\n}\nimpl Drop for File {\n    fn drop(&mut self) { unsafe { libc::close(self.handle); } }\n}\n",[36,2426,2427,2446,2454,2495,2526,2541,2545,2549,2562,2598],{"__ignoreMap":34},[39,2428,2429,2431,2433,2436,2439,2441,2444],{"class":41,"line":42},[39,2430,46],{"class":45},[39,2432,49],{"class":45},[39,2434,2435],{"class":52}," File",[39,2437,2438],{"class":56}," { handle",[39,2440,66],{"class":45},[39,2442,2443],{"class":52}," RawFd",[39,2445,285],{"class":56},[39,2447,2448,2450,2452],{"class":41,"line":60},[39,2449,219],{"class":45},[39,2451,2435],{"class":52},[39,2453,57],{"class":56},[39,2455,2456,2458,2460,2463,2466,2468,2470,2472,2474,2476,2479,2481,2484,2486,2489,2491,2493],{"class":41,"line":75},[39,2457,229],{"class":45},[39,2459,232],{"class":45},[39,2461,2462],{"class":52}," open",[39,2464,2465],{"class":56},"(path",[39,2467,66],{"class":45},[39,2469,1448],{"class":45},[39,2471,1451],{"class":52},[39,2473,390],{"class":56},[39,2475,241],{"class":45},[39,2477,2478],{"class":52}," std",[39,2480,708],{"class":45},[39,2482,2483],{"class":52},"io",[39,2485,708],{"class":45},[39,2487,2488],{"class":52},"Result",[39,2490,149],{"class":56},[39,2492,1062],{"class":244},[39,2494,545],{"class":56},[39,2496,2497,2500,2503,2505,2508,2510,2513,2515,2518,2520,2523],{"class":41,"line":88},[39,2498,2499],{"class":45},"        let",[39,2501,2502],{"class":56}," fd ",[39,2504,347],{"class":45},[39,2506,2507],{"class":45}," unsafe",[39,2509,335],{"class":56},[39,2511,2512],{"class":52},"libc",[39,2514,708],{"class":45},[39,2516,2517],{"class":52},"open",[39,2519,304],{"class":56},[39,2521,2522],{"class":45},"...",[39,2524,2525],{"class":56},") };\n",[39,2527,2528,2530,2532,2534,2536,2538],{"class":41,"line":101},[39,2529,551],{"class":52},[39,2531,304],{"class":56},[39,2533,1721],{"class":52},[39,2535,2438],{"class":56},[39,2537,66],{"class":45},[39,2539,2540],{"class":56}," fd })\n",[39,2542,2543],{"class":41,"line":114},[39,2544,291],{"class":56},[39,2546,2547],{"class":41,"line":120},[39,2548,117],{"class":56},[39,2550,2551,2553,2556,2558,2560],{"class":41,"line":127},[39,2552,219],{"class":45},[39,2554,2555],{"class":52}," Drop",[39,2557,1576],{"class":45},[39,2559,2435],{"class":52},[39,2561,57],{"class":56},[39,2563,2564,2566,2569,2571,2573,2575,2577,2580,2582,2584,2586,2589,2591,2593,2595],{"class":41,"line":139},[39,2565,1839],{"class":45},[39,2567,2568],{"class":52}," drop",[39,2570,304],{"class":56},[39,2572,1847],{"class":45},[39,2574,310],{"class":244},[39,2576,1099],{"class":56},[39,2578,2579],{"class":45},"unsafe",[39,2581,335],{"class":56},[39,2583,2512],{"class":52},[39,2585,708],{"class":45},[39,2587,2588],{"class":52},"close",[39,2590,304],{"class":56},[39,2592,338],{"class":244},[39,2594,341],{"class":45},[39,2596,2597],{"class":56},"handle); } }\n",[39,2599,2600],{"class":41,"line":158},[39,2601,117],{"class":56},[14,2603,2604],{},"No leak, no double-close, no use-after-close — all enforced by the compiler.",[18,2606,2608],{"id":2607},"_8-iterator-pattern","8. Iterator Pattern",[14,2610,2611],{},"Lazy, composable:",[26,2613,2614],{"language":28},[30,2615,2617],{"className":32,"code":2616,"language":28,"meta":34,"style":34},"let v: Vec\u003Ci32> = (1..100)\n    .filter(|x| x % 2 == 0)\n    .map(|x| x * x)\n    .take(10)\n    .collect();\n",[36,2618,2619,2652,2687,2709,2723],{"__ignoreMap":34},[39,2620,2621,2623,2625,2627,2629,2631,2634,2636,2638,2641,2644,2647,2649],{"class":41,"line":42},[39,2622,698],{"class":45},[39,2624,2035],{"class":56},[39,2626,66],{"class":45},[39,2628,1532],{"class":52},[39,2630,149],{"class":56},[39,2632,2633],{"class":52},"i32",[39,2635,1418],{"class":56},[39,2637,347],{"class":45},[39,2639,2640],{"class":56}," (",[39,2642,2643],{"class":244},"1",[39,2645,2646],{"class":45},"..",[39,2648,669],{"class":244},[39,2650,2651],{"class":56},")\n",[39,2653,2654,2657,2660,2662,2665,2668,2670,2673,2676,2679,2682,2685],{"class":41,"line":60},[39,2655,2656],{"class":45},"    .",[39,2658,2659],{"class":52},"filter",[39,2661,304],{"class":56},[39,2663,2664],{"class":45},"|",[39,2666,2667],{"class":56},"x",[39,2669,2664],{"class":45},[39,2671,2672],{"class":56}," x ",[39,2674,2675],{"class":45},"%",[39,2677,2678],{"class":244}," 2",[39,2680,2681],{"class":45}," ==",[39,2683,2684],{"class":244}," 0",[39,2686,2651],{"class":56},[39,2688,2689,2691,2694,2696,2698,2700,2702,2704,2706],{"class":41,"line":75},[39,2690,2656],{"class":45},[39,2692,2693],{"class":52},"map",[39,2695,304],{"class":56},[39,2697,2664],{"class":45},[39,2699,2667],{"class":56},[39,2701,2664],{"class":45},[39,2703,2672],{"class":56},[39,2705,2068],{"class":45},[39,2707,2708],{"class":56}," x)\n",[39,2710,2711,2713,2716,2718,2721],{"class":41,"line":88},[39,2712,2656],{"class":45},[39,2714,2715],{"class":52},"take",[39,2717,304],{"class":56},[39,2719,2720],{"class":244},"10",[39,2722,2651],{"class":56},[39,2724,2725,2727,2730],{"class":41,"line":101},[39,2726,2656],{"class":45},[39,2728,2729],{"class":52},"collect",[39,2731,1755],{"class":56},[14,2733,2734,2735,2738,2739,2741,2742,341],{},"Custom iterators implement ",[36,2736,2737],{},"Iterator::next",". ",[36,2740,2729],{}," builds any ",[36,2743,2744],{},"FromIterator",[18,2746,2748],{"id":2747},"_9-smart-constructor-pattern","9. Smart-Constructor Pattern",[26,2750,2751],{"language":28},[30,2752,2754],{"className":32,"code":2753,"language":28,"meta":34,"style":34},"pub struct Percent(u8);\nimpl Percent {\n    pub fn new(p: u8) -> Option\u003CSelf> {\n        if p \u003C= 100 { Some(Percent(p)) } else { None }\n    }\n}\n",[36,2755,2756,2771,2779,2807,2842,2846],{"__ignoreMap":34},[39,2757,2758,2760,2762,2765,2767,2769],{"class":41,"line":42},[39,2759,46],{"class":45},[39,2761,49],{"class":45},[39,2763,2764],{"class":52}," Percent",[39,2766,304],{"class":56},[39,2768,1524],{"class":52},[39,2770,798],{"class":56},[39,2772,2773,2775,2777],{"class":41,"line":60},[39,2774,219],{"class":45},[39,2776,2764],{"class":52},[39,2778,57],{"class":56},[39,2780,2781,2783,2785,2787,2790,2792,2795,2797,2799,2801,2803,2805],{"class":41,"line":75},[39,2782,229],{"class":45},[39,2784,232],{"class":45},[39,2786,235],{"class":52},[39,2788,2789],{"class":56},"(p",[39,2791,66],{"class":45},[39,2793,2794],{"class":52}," u8",[39,2796,390],{"class":56},[39,2798,241],{"class":45},[39,2800,146],{"class":52},[39,2802,149],{"class":56},[39,2804,1062],{"class":244},[39,2806,545],{"class":56},[39,2808,2809,2811,2814,2817,2820,2822,2825,2827,2830,2833,2835,2837,2840],{"class":41,"line":88},[39,2810,1083],{"class":45},[39,2812,2813],{"class":56}," p ",[39,2815,2816],{"class":45},"\u003C=",[39,2818,2819],{"class":244}," 100",[39,2821,335],{"class":56},[39,2823,2824],{"class":52},"Some",[39,2826,304],{"class":56},[39,2828,2829],{"class":52},"Percent",[39,2831,2832],{"class":56},"(p)) } ",[39,2834,1113],{"class":45},[39,2836,335],{"class":56},[39,2838,2839],{"class":52},"None",[39,2841,285],{"class":56},[39,2843,2844],{"class":41,"line":101},[39,2845,291],{"class":56},[39,2847,2848],{"class":41,"line":114},[39,2849,117],{"class":56},[14,2851,2852],{},"Never expose the inner; force construction through validation.",[18,2854,2856],{"id":2855},"_10-extension-trait","10. Extension Trait",[14,2858,2859],{},"Add methods to external types (with a wrapper):",[26,2861,2862],{"language":28},[30,2863,2865],{"className":32,"code":2864,"language":28,"meta":34,"style":34},"pub trait StrExt { fn shout(&self) -> String; }\nimpl StrExt for str { fn shout(&self) -> String { format!(\"{}!!!\", self.to_uppercase()) } }\nuse crate::StrExt;\n\"hi\".shout();\n",[36,2866,2867,2898,2948,2961],{"__ignoreMap":34},[39,2868,2869,2871,2873,2876,2878,2880,2883,2885,2887,2889,2891,2893,2895],{"class":41,"line":42},[39,2870,46],{"class":45},[39,2872,1494],{"class":45},[39,2874,2875],{"class":52}," StrExt",[39,2877,335],{"class":56},[39,2879,1502],{"class":45},[39,2881,2882],{"class":52}," shout",[39,2884,304],{"class":56},[39,2886,1067],{"class":45},[39,2888,338],{"class":244},[39,2890,390],{"class":56},[39,2892,241],{"class":45},[39,2894,69],{"class":52},[39,2896,2897],{"class":56},"; }\n",[39,2899,2900,2902,2904,2906,2908,2910,2912,2914,2916,2918,2920,2922,2924,2926,2928,2931,2933,2936,2938,2940,2942,2945],{"class":41,"line":60},[39,2901,219],{"class":45},[39,2903,2875],{"class":52},[39,2905,1576],{"class":45},[39,2907,1076],{"class":52},[39,2909,335],{"class":56},[39,2911,1502],{"class":45},[39,2913,2882],{"class":52},[39,2915,304],{"class":56},[39,2917,1067],{"class":45},[39,2919,338],{"class":244},[39,2921,390],{"class":56},[39,2923,241],{"class":45},[39,2925,69],{"class":52},[39,2927,335],{"class":56},[39,2929,2930],{"class":52},"format!",[39,2932,304],{"class":56},[39,2934,2935],{"class":582},"\"{}!!!\"",[39,2937,540],{"class":56},[39,2939,338],{"class":244},[39,2941,341],{"class":45},[39,2943,2944],{"class":52},"to_uppercase",[39,2946,2947],{"class":56},"()) } }\n",[39,2949,2950,2953,2956,2959],{"class":41,"line":75},[39,2951,2952],{"class":45},"use",[39,2954,2955],{"class":45}," crate::",[39,2957,2958],{"class":52},"StrExt",[39,2960,748],{"class":56},[39,2962,2963,2966,2968,2971],{"class":41,"line":88},[39,2964,2965],{"class":582},"\"hi\"",[39,2967,341],{"class":45},[39,2969,2970],{"class":52},"shout",[39,2972,1755],{"class":56},[14,2974,2975,2976,2980],{},"You can't implement an external trait for an external type (orphan rule), but you ",[2977,2978,2979],"em",{},"can"," implement your own trait for any type.",[18,2982,2984],{"id":2983},"_11-handle-raii-wrapper-around-foreign-types","11. Handle \u002F RAII Wrapper around Foreign Types",[26,2986,2987],{"language":28},[30,2988,2990],{"className":32,"code":2989,"language":28,"meta":34,"style":34},"pub struct Database(*mut bindings::sqlite3);\nimpl Drop for Database { fn drop(&mut self) { unsafe { bindings::close(self.0) } } }\n",[36,2991,2992,3014],{"__ignoreMap":34},[39,2993,2994,2996,2998,3001,3003,3006,3009,3011],{"class":41,"line":42},[39,2995,46],{"class":45},[39,2997,49],{"class":45},[39,2999,3000],{"class":52}," Database",[39,3002,304],{"class":56},[39,3004,3005],{"class":45},"*mut",[39,3007,3008],{"class":52}," bindings",[39,3010,708],{"class":45},[39,3012,3013],{"class":56},"sqlite3);\n",[39,3015,3016,3018,3020,3022,3024,3026,3028,3030,3032,3034,3036,3038,3040,3042,3045,3047,3049,3051,3053,3055,3058],{"class":41,"line":60},[39,3017,219],{"class":45},[39,3019,2555],{"class":52},[39,3021,1576],{"class":45},[39,3023,3000],{"class":52},[39,3025,335],{"class":56},[39,3027,1502],{"class":45},[39,3029,2568],{"class":52},[39,3031,304],{"class":56},[39,3033,1847],{"class":45},[39,3035,310],{"class":244},[39,3037,1099],{"class":56},[39,3039,2579],{"class":45},[39,3041,335],{"class":56},[39,3043,3044],{"class":52},"bindings",[39,3046,708],{"class":45},[39,3048,2588],{"class":52},[39,3050,304],{"class":56},[39,3052,338],{"class":244},[39,3054,341],{"class":45},[39,3056,3057],{"class":244},"0",[39,3059,3060],{"class":56},") } } }\n",[18,3062,3064,3065,1151,3067,3070],{"id":3063},"_12-frominto-for-conversions","12. ",[36,3066,1150],{},[36,3068,3069],{},"Into"," for Conversions",[26,3072,3073],{"language":28},[30,3074,3076],{"className":32,"code":3075,"language":28,"meta":34,"style":34},"impl From\u003CRawData> for Processed { fn from(r: RawData) -> Self { \u002F* ... *\u002F } }\nlet p: Processed = raw.into();\n",[36,3077,3078,3124],{"__ignoreMap":34},[39,3079,3080,3082,3085,3087,3090,3092,3094,3097,3099,3101,3104,3107,3109,3112,3114,3116,3118,3120,3122],{"class":41,"line":42},[39,3081,219],{"class":45},[39,3083,3084],{"class":52}," From",[39,3086,149],{"class":56},[39,3088,3089],{"class":52},"RawData",[39,3091,1418],{"class":56},[39,3093,2388],{"class":45},[39,3095,3096],{"class":52}," Processed",[39,3098,335],{"class":56},[39,3100,1502],{"class":45},[39,3102,3103],{"class":52}," from",[39,3105,3106],{"class":56},"(r",[39,3108,66],{"class":45},[39,3110,3111],{"class":52}," RawData",[39,3113,390],{"class":56},[39,3115,241],{"class":45},[39,3117,245],{"class":244},[39,3119,335],{"class":56},[39,3121,829],{"class":828},[39,3123,876],{"class":56},[39,3125,3126,3128,3131,3133,3135,3138,3141,3143,3145],{"class":41,"line":60},[39,3127,698],{"class":45},[39,3129,3130],{"class":56}," p",[39,3132,66],{"class":45},[39,3134,3096],{"class":52},[39,3136,3137],{"class":45}," =",[39,3139,3140],{"class":56}," raw",[39,3142,341],{"class":45},[39,3144,358],{"class":52},[39,3146,1755],{"class":56},[14,3148,3149,3150,3152,3153,3155],{},"Idiomatic conversion path. Implement ",[36,3151,1150],{},", never ",[36,3154,3069],{}," directly.",[18,3157,3159,3160,1151,3163,3166],{"id":3158},"_13-asrefasmut-for-flexible-borrowing","13. ",[36,3161,3162],{},"AsRef",[36,3164,3165],{},"AsMut"," for Flexible Borrowing",[26,3168,3169],{"language":28},[30,3170,3172],{"className":32,"code":3171,"language":28,"meta":34,"style":34},"pub fn open\u003CP: AsRef\u003CPath>>(path: P) { let p = path.as_ref(); \u002F* ... *\u002F }\nopen(\"file.txt\"); open(Path::new(\"f\")); open(String::from(\"f\"));\n",[36,3173,3174,3227],{"__ignoreMap":34},[39,3175,3176,3178,3180,3182,3184,3187,3189,3192,3194,3197,3200,3202,3205,3207,3209,3211,3213,3215,3217,3220,3223,3225],{"class":41,"line":42},[39,3177,46],{"class":45},[39,3179,232],{"class":45},[39,3181,2462],{"class":52},[39,3183,149],{"class":56},[39,3185,3186],{"class":52},"P",[39,3188,66],{"class":45},[39,3190,3191],{"class":52}," AsRef",[39,3193,149],{"class":56},[39,3195,3196],{"class":52},"Path",[39,3198,3199],{"class":56},">>(path",[39,3201,66],{"class":45},[39,3203,3204],{"class":52}," P",[39,3206,1099],{"class":56},[39,3208,698],{"class":45},[39,3210,2813],{"class":56},[39,3212,347],{"class":45},[39,3214,2180],{"class":56},[39,3216,341],{"class":45},[39,3218,3219],{"class":52},"as_ref",[39,3221,3222],{"class":56},"(); ",[39,3224,829],{"class":828},[39,3226,285],{"class":56},[39,3228,3229,3231,3233,3236,3239,3241,3243,3245,3247,3249,3251,3254,3257,3259,3261,3263,3265,3268,3270,3272],{"class":41,"line":60},[39,3230,2517],{"class":52},[39,3232,304],{"class":56},[39,3234,3235],{"class":582},"\"file.txt\"",[39,3237,3238],{"class":56},"); ",[39,3240,2517],{"class":52},[39,3242,304],{"class":56},[39,3244,3196],{"class":52},[39,3246,708],{"class":45},[39,3248,711],{"class":52},[39,3250,304],{"class":56},[39,3252,3253],{"class":582},"\"f\"",[39,3255,3256],{"class":56},")); ",[39,3258,2517],{"class":52},[39,3260,304],{"class":56},[39,3262,152],{"class":52},[39,3264,708],{"class":45},[39,3266,3267],{"class":52},"from",[39,3269,304],{"class":56},[39,3271,3253],{"class":582},[39,3273,3274],{"class":56},"));\n",[18,3276,3278,3279],{"id":3277},"_14-error-conversion-via","14. Error-Conversion via ",[36,3280,589],{},[26,3282,3283],{"language":28},[30,3284,3286],{"className":32,"code":3285,"language":28,"meta":34,"style":34},"pub fn run() -> Result\u003C(), AppError> {\n    let n: i32 = \"x\".parse()?;     \u002F\u002F uses From\u003CParseIntError> for AppError\n    Ok(())\n}\n",[36,3287,3288,3311,3342,3350],{"__ignoreMap":34},[39,3289,3290,3292,3294,3297,3299,3301,3303,3306,3309],{"class":41,"line":42},[39,3291,46],{"class":45},[39,3293,232],{"class":45},[39,3295,3296],{"class":52}," run",[39,3298,238],{"class":56},[39,3300,241],{"class":45},[39,3302,532],{"class":52},[39,3304,3305],{"class":56},"\u003C(), ",[39,3307,3308],{"class":52},"AppError",[39,3310,545],{"class":56},[39,3312,3313,3315,3318,3320,3323,3325,3327,3329,3332,3334,3336,3339],{"class":41,"line":60},[39,3314,1738],{"class":45},[39,3316,3317],{"class":56}," n",[39,3319,66],{"class":45},[39,3321,3322],{"class":52}," i32",[39,3324,3137],{"class":45},[39,3326,2344],{"class":582},[39,3328,341],{"class":45},[39,3330,3331],{"class":52},"parse",[39,3333,714],{"class":56},[39,3335,589],{"class":45},[39,3337,3338],{"class":56},";     ",[39,3340,3341],{"class":828},"\u002F\u002F uses From\u003CParseIntError> for AppError\n",[39,3343,3344,3347],{"class":41,"line":75},[39,3345,3346],{"class":52},"    Ok",[39,3348,3349],{"class":56},"(())\n",[39,3351,3352],{"class":41,"line":88},[39,3353,117],{"class":56},[14,3355,3356,3359,3360,3363,3364,3366],{},[36,3357,3358],{},"thiserror","'s ",[36,3361,3362],{},"#[from]"," generates the ",[36,3365,1150],{}," impl automatically.",[18,3368,3370],{"id":3369},"_15-trait-composition-via-supertraits","15. Trait Composition via Supertraits",[26,3372,3373],{"language":28},[30,3374,3376],{"className":32,"code":3375,"language":28,"meta":34,"style":34},"pub trait Service: Send + Sync + Debug {\n    fn call(&self, req: Request) -> Response;\n}\n",[36,3377,3378,3405,3435],{"__ignoreMap":34},[39,3379,3380,3382,3384,3387,3389,3392,3395,3398,3400,3403],{"class":41,"line":42},[39,3381,46],{"class":45},[39,3383,1494],{"class":45},[39,3385,3386],{"class":52}," Service",[39,3388,66],{"class":45},[39,3390,3391],{"class":52}," Send",[39,3393,3394],{"class":45}," +",[39,3396,3397],{"class":52}," Sync",[39,3399,3394],{"class":45},[39,3401,3402],{"class":52}," Debug",[39,3404,57],{"class":56},[39,3406,3407,3409,3412,3414,3416,3418,3421,3423,3426,3428,3430,3433],{"class":41,"line":60},[39,3408,1839],{"class":45},[39,3410,3411],{"class":52}," call",[39,3413,304],{"class":56},[39,3415,1067],{"class":45},[39,3417,338],{"class":244},[39,3419,3420],{"class":56},", req",[39,3422,66],{"class":45},[39,3424,3425],{"class":52}," Request",[39,3427,390],{"class":56},[39,3429,241],{"class":45},[39,3431,3432],{"class":52}," Response",[39,3434,748],{"class":56},[39,3436,3437],{"class":41,"line":75},[39,3438,117],{"class":56},[14,3440,3441],{},"A supertrait bound requires all subtraits. Implementations must provide all.",[18,3443,3445],{"id":3444},"_16-default-trait-for-defaults","16. Default Trait for Defaults",[26,3447,3448],{"language":28},[30,3449,3451],{"className":32,"code":3450,"language":28,"meta":34,"style":34},"#[derive(Default)]\npub struct Config { pub host: String, pub port: u16 }\nlet c = Config { port: 8080, ..Default::default() };\n",[36,3452,3453,3464,3495],{"__ignoreMap":34},[39,3454,3455,3458,3461],{"class":41,"line":42},[39,3456,3457],{"class":56},"#[derive(",[39,3459,3460],{"class":52},"Default",[39,3462,3463],{"class":56},")]\n",[39,3465,3466,3468,3470,3473,3475,3477,3479,3481,3483,3485,3487,3489,3491,3493],{"class":41,"line":60},[39,3467,46],{"class":45},[39,3469,49],{"class":45},[39,3471,3472],{"class":52}," Config",[39,3474,335],{"class":56},[39,3476,46],{"class":45},[39,3478,301],{"class":56},[39,3480,66],{"class":45},[39,3482,69],{"class":52},[39,3484,540],{"class":56},[39,3486,46],{"class":45},[39,3488,375],{"class":56},[39,3490,66],{"class":45},[39,3492,83],{"class":52},[39,3494,285],{"class":56},[39,3496,3497,3499,3501,3503,3505,3508,3510,3513,3515,3517,3519,3521,3524],{"class":41,"line":75},[39,3498,698],{"class":45},[39,3500,2391],{"class":56},[39,3502,347],{"class":45},[39,3504,3472],{"class":52},[39,3506,3507],{"class":56}," { port",[39,3509,66],{"class":45},[39,3511,3512],{"class":244}," 8080",[39,3514,540],{"class":56},[39,3516,2646],{"class":45},[39,3518,3460],{"class":52},[39,3520,708],{"class":45},[39,3522,3523],{"class":52},"default",[39,3525,3526],{"class":56},"() };\n",[18,3528,3530],{"id":3529},"_17-phantom-type-parameters","17. Phantom Type Parameters",[26,3532,3533],{"language":28},[30,3534,3536],{"className":32,"code":3535,"language":28,"meta":34,"style":34},"pub struct Id\u003CT>(u64, PhantomData\u003CT>);\npub struct User; pub struct Post;\ntype UserId = Id\u003CUser>; type PostId = Id\u003CPost>;\n",[36,3537,3538,3570,3590],{"__ignoreMap":34},[39,3539,3540,3542,3544,3547,3549,3552,3555,3558,3560,3563,3565,3567],{"class":41,"line":42},[39,3541,46],{"class":45},[39,3543,49],{"class":45},[39,3545,3546],{"class":52}," Id",[39,3548,149],{"class":56},[39,3550,3551],{"class":52},"T",[39,3553,3554],{"class":56},">(",[39,3556,3557],{"class":52},"u64",[39,3559,540],{"class":56},[39,3561,3562],{"class":52},"PhantomData",[39,3564,149],{"class":56},[39,3566,3551],{"class":52},[39,3568,3569],{"class":56},">);\n",[39,3571,3572,3574,3576,3579,3581,3583,3585,3588],{"class":41,"line":60},[39,3573,46],{"class":45},[39,3575,49],{"class":45},[39,3577,3578],{"class":52}," User",[39,3580,1187],{"class":56},[39,3582,46],{"class":45},[39,3584,49],{"class":45},[39,3586,3587],{"class":52}," Post",[39,3589,748],{"class":56},[39,3591,3592,3595,3597,3599,3601,3603,3606,3609,3611,3614,3616,3618,3620,3623],{"class":41,"line":75},[39,3593,3594],{"class":45},"type",[39,3596,998],{"class":52},[39,3598,3137],{"class":45},[39,3600,3546],{"class":52},[39,3602,149],{"class":56},[39,3604,3605],{"class":52},"User",[39,3607,3608],{"class":56},">; ",[39,3610,3594],{"class":45},[39,3612,3613],{"class":52}," PostId",[39,3615,3137],{"class":45},[39,3617,3546],{"class":52},[39,3619,149],{"class":56},[39,3621,3622],{"class":52},"Post",[39,3624,3625],{"class":56},">;\n",[14,3627,3628],{},"Same numeric value, distinct types — prevents mixing IDs.",[18,3630,3632],{"id":3631},"_18-crtp-disabled-in-safe-rust","18. CRTP (Disabled in safe Rust)",[14,3634,3635,3636,3638,3639,3641],{},"You can't easily do \"compile-time virtual\" the way C++ does. The closest is a trait with an associated type for ",[36,3637,1062],{},"-like dispatch, or ",[36,3640,2309],{}," for runtime. The typestate pattern covers many use cases.",[18,3643,3645],{"id":3644},"_19-tagged-unions-via-enums","19. Tagged Unions via Enums",[14,3647,3648],{},"The Rust-native \"tagged union\" — see the Enums chapter.",[18,3650,3652],{"id":3651},"_20-dependency-injection-via-traits","20. Dependency Injection via Traits",[26,3654,3655],{"language":28},[30,3656,3658],{"className":32,"code":3657,"language":28,"meta":34,"style":34},"pub trait Clock { fn now(&self) -> Instant; }\npub struct RealClock; impl Clock for RealClock { fn now(&self) -> Instant { Instant::now() } }\npub struct MockClock(Instant); impl Clock for MockClock { fn now(&self) -> Instant { self.0 } }\n\npub struct Service\u003CC: Clock> { clock: C }\n",[36,3659,3660,3691,3740,3791,3795],{"__ignoreMap":34},[39,3661,3662,3664,3666,3669,3671,3673,3676,3678,3680,3682,3684,3686,3689],{"class":41,"line":42},[39,3663,46],{"class":45},[39,3665,1494],{"class":45},[39,3667,3668],{"class":52}," Clock",[39,3670,335],{"class":56},[39,3672,1502],{"class":45},[39,3674,3675],{"class":52}," now",[39,3677,304],{"class":56},[39,3679,1067],{"class":45},[39,3681,338],{"class":244},[39,3683,390],{"class":56},[39,3685,241],{"class":45},[39,3687,3688],{"class":52}," Instant",[39,3690,2897],{"class":56},[39,3692,3693,3695,3697,3700,3702,3704,3706,3708,3710,3712,3714,3716,3718,3720,3722,3724,3726,3728,3730,3733,3735,3738],{"class":41,"line":60},[39,3694,46],{"class":45},[39,3696,49],{"class":45},[39,3698,3699],{"class":52}," RealClock",[39,3701,1187],{"class":56},[39,3703,219],{"class":45},[39,3705,3668],{"class":52},[39,3707,1576],{"class":45},[39,3709,3699],{"class":52},[39,3711,335],{"class":56},[39,3713,1502],{"class":45},[39,3715,3675],{"class":52},[39,3717,304],{"class":56},[39,3719,1067],{"class":45},[39,3721,338],{"class":244},[39,3723,390],{"class":56},[39,3725,241],{"class":45},[39,3727,3688],{"class":52},[39,3729,335],{"class":56},[39,3731,3732],{"class":52},"Instant",[39,3734,708],{"class":45},[39,3736,3737],{"class":52},"now",[39,3739,1623],{"class":56},[39,3741,3742,3744,3746,3749,3751,3753,3755,3757,3759,3761,3763,3765,3767,3769,3771,3773,3775,3777,3779,3781,3783,3785,3787,3789],{"class":41,"line":75},[39,3743,46],{"class":45},[39,3745,49],{"class":45},[39,3747,3748],{"class":52}," MockClock",[39,3750,304],{"class":56},[39,3752,3732],{"class":52},[39,3754,3238],{"class":56},[39,3756,219],{"class":45},[39,3758,3668],{"class":52},[39,3760,1576],{"class":45},[39,3762,3748],{"class":52},[39,3764,335],{"class":56},[39,3766,1502],{"class":45},[39,3768,3675],{"class":52},[39,3770,304],{"class":56},[39,3772,1067],{"class":45},[39,3774,338],{"class":244},[39,3776,390],{"class":56},[39,3778,241],{"class":45},[39,3780,3688],{"class":52},[39,3782,335],{"class":56},[39,3784,338],{"class":244},[39,3786,341],{"class":45},[39,3788,3057],{"class":244},[39,3790,876],{"class":56},[39,3792,3793],{"class":41,"line":88},[39,3794,124],{"emptyLinePlaceholder":123},[39,3796,3797,3799,3801,3803,3805,3807,3809,3811,3814,3816,3819],{"class":41,"line":101},[39,3798,46],{"class":45},[39,3800,49],{"class":45},[39,3802,3386],{"class":52},[39,3804,149],{"class":56},[39,3806,1696],{"class":52},[39,3808,66],{"class":45},[39,3810,3668],{"class":52},[39,3812,3813],{"class":56},"> { clock",[39,3815,66],{"class":45},[39,3817,3818],{"class":52}," C",[39,3820,285],{"class":56},[14,3822,3823,3824,3827,3828,3831],{},"Tests inject ",[36,3825,3826],{},"MockClock","; production uses ",[36,3829,3830],{},"RealClock",". No global mutable state needed.",[18,3833,3835],{"id":3834},"_21-avoid-global-mutable-state","21. Avoid Global Mutable State",[14,3837,3838,3839,3842,3843,3846],{},"Use dependency injection, or ",[36,3840,3841],{},"OnceLock"," for genuinely global immutable data. Mutable globals are a smell — wrap in ",[36,3844,3845],{},"Arc\u003CMutex\u003CT>>"," if needed.",[18,3848,3850,3851,3853],{"id":3849},"_22-use-liberally","22. Use ",[36,3852,589],{}," Liberally",[14,3855,3856,3857,3860,3861,3863],{},"Idiomatic error propagation. Avoid deeply nested ",[36,3858,3859],{},"match"," when ",[36,3862,589],{}," works.",[18,3865,3867],{"id":3866},"_23-use-iterators-over-loops","23. Use Iterators Over Loops",[26,3869,3870],{"language":28},[30,3871,3873],{"className":32,"code":3872,"language":28,"meta":34,"style":34},"\u002F\u002F Idiomatic\nlet sum: i32 = v.iter().map(|x| x * 2).sum();\n\n\u002F\u002F Less idiomatic\nlet mut sum = 0;\nfor x in &v { sum += x * 2; }\n",[36,3874,3875,3880,3929,3933,3938,3953],{"__ignoreMap":34},[39,3876,3877],{"class":41,"line":42},[39,3878,3879],{"class":828},"\u002F\u002F Idiomatic\n",[39,3881,3882,3884,3887,3889,3891,3893,3895,3897,3900,3902,3904,3906,3908,3910,3912,3914,3916,3918,3920,3922,3924,3927],{"class":41,"line":60},[39,3883,698],{"class":45},[39,3885,3886],{"class":56}," sum",[39,3888,66],{"class":45},[39,3890,3322],{"class":52},[39,3892,3137],{"class":45},[39,3894,2035],{"class":56},[39,3896,341],{"class":45},[39,3898,3899],{"class":52},"iter",[39,3901,714],{"class":56},[39,3903,341],{"class":45},[39,3905,2693],{"class":52},[39,3907,304],{"class":56},[39,3909,2664],{"class":45},[39,3911,2667],{"class":56},[39,3913,2664],{"class":45},[39,3915,2672],{"class":56},[39,3917,2068],{"class":45},[39,3919,2678],{"class":244},[39,3921,586],{"class":56},[39,3923,341],{"class":45},[39,3925,3926],{"class":52},"sum",[39,3928,1755],{"class":56},[39,3930,3931],{"class":41,"line":75},[39,3932,124],{"emptyLinePlaceholder":123},[39,3934,3935],{"class":41,"line":88},[39,3936,3937],{"class":828},"\u002F\u002F Less idiomatic\n",[39,3939,3940,3942,3944,3947,3949,3951],{"class":41,"line":101},[39,3941,698],{"class":45},[39,3943,1741],{"class":45},[39,3945,3946],{"class":56}," sum ",[39,3948,347],{"class":45},[39,3950,2684],{"class":244},[39,3952,748],{"class":56},[39,3954,3955,3957,3959,3961,3963,3966,3969,3971,3973,3975],{"class":41,"line":114},[39,3956,2388],{"class":45},[39,3958,2672],{"class":56},[39,3960,1766],{"class":45},[39,3962,1448],{"class":45},[39,3964,3965],{"class":56},"v { sum ",[39,3967,3968],{"class":45},"+=",[39,3970,2672],{"class":56},[39,3972,2068],{"class":45},[39,3974,2678],{"class":244},[39,3976,2897],{"class":56},[14,3978,3979],{},"The iterator form is equally fast (zero-cost) and more declarative.",[18,3981,3983,3984,3987],{"id":3982},"_24-avoid-unwrap-in-public-code","24. Avoid ",[36,3985,3986],{},"unwrap"," in Public Code",[14,3989,3990,3991,3993,3994,3996,3997,3999,4000,4003],{},"In tests, ",[36,3992,3986],{}," is fine. In production APIs, use ",[36,3995,589],{},", return ",[36,3998,2488],{},", or ",[36,4001,4002],{},"expect(\"invariant message\")"," if you really can't fail.",[18,4005,4007],{"id":4006},"_25-documentation-comments","25. Documentation Comments",[26,4009,4010],{"language":28},[30,4011,4013],{"className":32,"code":4012,"language":28,"meta":34,"style":34},"\u002F\u002F\u002F Adds two numbers.\n\u002F\u002F\u002F\n\u002F\u002F\u002F # Panics\n\u002F\u002F\u002F Panics if overflow occurs (debug builds).\n\u002F\u002F\u002F\n\u002F\u002F\u002F # Examples\n\u002F\u002F\u002F ```\n\u002F\u002F\u002F use my::add;\n\u002F\u002F\u002F assert_eq!(add(2, 2), 4);\n\u002F\u002F\u002F ```\npub fn add(a: i32, b: i32) -> i32 { a + b }\n",[36,4014,4015,4020,4025,4030,4035,4039,4044,4049,4054,4059,4063],{"__ignoreMap":34},[39,4016,4017],{"class":41,"line":42},[39,4018,4019],{"class":828},"\u002F\u002F\u002F Adds two numbers.\n",[39,4021,4022],{"class":41,"line":60},[39,4023,4024],{"class":828},"\u002F\u002F\u002F\n",[39,4026,4027],{"class":41,"line":75},[39,4028,4029],{"class":828},"\u002F\u002F\u002F # Panics\n",[39,4031,4032],{"class":41,"line":88},[39,4033,4034],{"class":828},"\u002F\u002F\u002F Panics if overflow occurs (debug builds).\n",[39,4036,4037],{"class":41,"line":101},[39,4038,4024],{"class":828},[39,4040,4041],{"class":41,"line":114},[39,4042,4043],{"class":828},"\u002F\u002F\u002F # Examples\n",[39,4045,4046],{"class":41,"line":120},[39,4047,4048],{"class":828},"\u002F\u002F\u002F ```\n",[39,4050,4051],{"class":41,"line":127},[39,4052,4053],{"class":828},"\u002F\u002F\u002F use my::add;\n",[39,4055,4056],{"class":41,"line":139},[39,4057,4058],{"class":828},"\u002F\u002F\u002F assert_eq!(add(2, 2), 4);\n",[39,4060,4061],{"class":41,"line":158},[39,4062,4048],{"class":828},[39,4064,4065,4067,4069,4072,4075,4077,4079,4082,4084,4086,4088,4090,4092,4095,4098],{"class":41,"line":174},[39,4066,46],{"class":45},[39,4068,232],{"class":45},[39,4070,4071],{"class":52}," add",[39,4073,4074],{"class":56},"(a",[39,4076,66],{"class":45},[39,4078,3322],{"class":52},[39,4080,4081],{"class":56},", b",[39,4083,66],{"class":45},[39,4085,3322],{"class":52},[39,4087,390],{"class":56},[39,4089,241],{"class":45},[39,4091,3322],{"class":52},[39,4093,4094],{"class":56}," { a ",[39,4096,4097],{"class":45},"+",[39,4099,4100],{"class":56}," b }\n",[1136,4102,4103,4113],{},[1139,4104,4105,4108,4109,4112],{},[36,4106,4107],{},"\u002F\u002F\u002F"," for items, ",[36,4110,4111],{},"\u002F\u002F!"," for crates\u002Fmodules.",[1139,4114,4115,4116,540,4119,540,4122,540,4125,540,4128,341],{},"Sections: ",[36,4117,4118],{},"# Panics",[36,4120,4121],{},"# Errors",[36,4123,4124],{},"# Examples",[36,4126,4127],{},"# Safety",[36,4129,4130],{},"# Arguments",[18,4132,4134],{"id":4133},"_26-naming-conventions","26. Naming Conventions",[1136,4136,4137,4143,4149,4155],{},[1139,4138,4139,4142],{},[36,4140,4141],{},"snake_case"," for functions, variables, modules.",[1139,4144,4145,4148],{},[36,4146,4147],{},"CamelCase"," for types\u002Ftraits\u002Fenum variants.",[1139,4150,4151,4154],{},[36,4152,4153],{},"SCREAMING_SNAKE_CASE"," for constants and statics.",[1139,4156,4157,4158,540,4161,540,4164,540,4167,341],{},"Lifetime params: ",[36,4159,4160],{},"'a",[36,4162,4163],{},"'b",[36,4165,4166],{},"'src",[36,4168,4169],{},"'arena",[18,4171,4173],{"id":4172},"_27-error-vs-option-heuristic","27. Error vs Option Heuristic",[1136,4175,4176,4182],{},[1139,4177,4178,4181],{},[36,4179,4180],{},"Option"," for \"absent\" (looking up a key, optional config).",[1139,4183,4184,4186],{},[36,4185,2488],{}," for \"operation failed\" (parse, IO, network).",[18,4188,4190],{"id":4189},"_28-when-to-box-vs-generic","28. When to Box vs Generic",[1136,4192,4193,4196],{},[1139,4194,4195],{},"Generic: monomorphization is acceptable (caller can static-dispatch).",[1139,4197,4198,4201],{},[36,4199,4200],{},"Box\u003Cdyn>",": heterogeneous collections, runtime polymorphism, smaller binary.",[18,4203,4205,4206,4209],{"id":4204},"_29-cow-for-borrowed-or-owned","29. ",[36,4207,4208],{},"Cow"," for Borrowed-or-Owned",[26,4211,4212],{"language":28},[30,4213,4215],{"className":32,"code":4214,"language":28,"meta":34,"style":34},"pub fn normalize(s: &str) -> Cow\u003Cstr> {\n    if s.chars().any(|c| c.is_uppercase()) {\n        Cow::Owned(s.to_lowercase())\n    } else {\n        Cow::Borrowed(s)\n    }\n}\n",[36,4216,4217,4247,4286,4306,4315,4327,4331],{"__ignoreMap":34},[39,4218,4219,4221,4223,4226,4228,4230,4232,4234,4236,4238,4241,4243,4245],{"class":41,"line":42},[39,4220,46],{"class":45},[39,4222,232],{"class":45},[39,4224,4225],{"class":52}," normalize",[39,4227,1047],{"class":56},[39,4229,66],{"class":45},[39,4231,1448],{"class":45},[39,4233,1451],{"class":52},[39,4235,390],{"class":56},[39,4237,241],{"class":45},[39,4239,4240],{"class":52}," Cow",[39,4242,149],{"class":56},[39,4244,1451],{"class":52},[39,4246,545],{"class":56},[39,4248,4249,4252,4254,4256,4259,4261,4263,4266,4268,4270,4273,4275,4278,4280,4283],{"class":41,"line":60},[39,4250,4251],{"class":45},"    if",[39,4253,1086],{"class":56},[39,4255,341],{"class":45},[39,4257,4258],{"class":52},"chars",[39,4260,714],{"class":56},[39,4262,341],{"class":45},[39,4264,4265],{"class":52},"any",[39,4267,304],{"class":56},[39,4269,2664],{"class":45},[39,4271,4272],{"class":56},"c",[39,4274,2664],{"class":45},[39,4276,4277],{"class":56}," c",[39,4279,341],{"class":45},[39,4281,4282],{"class":52},"is_uppercase",[39,4284,4285],{"class":56},"()) {\n",[39,4287,4288,4291,4293,4296,4298,4300,4303],{"class":41,"line":75},[39,4289,4290],{"class":52},"        Cow",[39,4292,708],{"class":45},[39,4294,4295],{"class":52},"Owned",[39,4297,1047],{"class":56},[39,4299,341],{"class":45},[39,4301,4302],{"class":52},"to_lowercase",[39,4304,4305],{"class":56},"())\n",[39,4307,4308,4311,4313],{"class":41,"line":88},[39,4309,4310],{"class":56},"    } ",[39,4312,1113],{"class":45},[39,4314,57],{"class":56},[39,4316,4317,4319,4321,4324],{"class":41,"line":101},[39,4318,4290],{"class":52},[39,4320,708],{"class":45},[39,4322,4323],{"class":52},"Borrowed",[39,4325,4326],{"class":56},"(s)\n",[39,4328,4329],{"class":41,"line":114},[39,4330,291],{"class":56},[39,4332,4333],{"class":41,"line":120},[39,4334,117],{"class":56},[14,4336,4337],{},"Avoids cloning when no transformation is needed.",[18,4339,4341],{"id":4340},"_30-avoid-premature-abstraction","30. Avoid Premature Abstraction",[14,4343,4344,4345,4347],{},"Don't define traits until you have a second implementation. Don't reach for ",[36,4346,2309],{}," until you need runtime polymorphism. Don't introduce generics until you have a second type. \"Rule of three\" — abstract when you see repetition.",[18,4349,4351],{"id":4350},"common-anti-patterns","Common Anti-Patterns",[1136,4353,4354,4364,4373,4383,4396,4402,4411,4419,4425,4438],{},[1139,4355,4356,4363],{},[4357,4358,4359,4360,4362],"strong",{},"Implementing ",[36,4361,1160],{}," for non-smart-pointer types",": misleading. Use explicit methods.",[1139,4365,4366,4372],{},[4357,4367,4368,4369],{},"Overusing ",[36,4370,4371],{},"Box\u003Cdyn Trait>",": kills performance and inlining; prefer generics.",[1139,4374,4375,4380,4381,341],{},[4357,4376,4377,4379],{},[36,4378,3986],{}," everywhere",": panics on edge cases. Use ",[36,4382,589],{},[1139,4384,4385,4390,4391,755,4393,341],{},[4357,4386,4387,4388,4379],{},"Returning ",[36,4389,152],{},": returns ownership unnecessarily; consider ",[36,4392,4208],{},[36,4394,4395],{},"&'static str",[1139,4397,4398,4401],{},[4357,4399,4400],{},"God objects",": huge structs with all state. Split by responsibility.",[1139,4403,4404,4410],{},[4357,4405,4406,4407,4409],{},"Inheriting via ",[36,4408,1160],{}," chains",": doesn't work like OOP inheritance; produces confusing method resolution.",[1139,4412,4413,4418],{},[4357,4414,4415,4417],{},[36,4416,2579],{}," to silence borrow errors",": the borrow checker is right; restructure.",[1139,4420,4421,4424],{},[4357,4422,4423],{},"Trait objects for performance-critical code",": vtable dispatch is slow; genericize.",[1139,4426,4427,4433,4434,4437],{},[4357,4428,4429,4432],{},[36,4430,4431],{},"Vec\u003CVec\u003CT>>"," for matrices",": cache-unfriendly; use a flat ",[36,4435,4436],{},"Vec\u003CT>"," with row-major indexing.",[1139,4439,4440,4443],{},[4357,4441,4442],{},"Mutable globals",": makes testing and reasoning hard. Inject dependencies.",[18,4445,4447],{"id":4446},"idioms-cheat-sheet","Idioms Cheat Sheet",[1136,4449,4450,4459,4466,4475,4483,4488,4499,4505,4511],{},[1139,4451,4452,4455,4456,4458],{},[36,4453,4454],{},"if let"," over ",[36,4457,3859],{}," for single-arm.",[1139,4460,4461,4463,4464,341],{},[36,4462,589],{}," over nested ",[36,4465,3859],{},[1139,4467,4468,4455,4471,4474],{},[36,4469,4470],{},"Rc::clone(&rc)",[36,4472,4473],{},"rc.clone()"," (clarity).",[1139,4476,4477,4455,4480,341],{},[36,4478,4479],{},".iter()",[36,4481,4482],{},"for i in 0..v.len()",[1139,4484,4485,4487],{},[36,4486,2930],{}," over manual string concatenation.",[1139,4489,4490,1151,4493,4455,4496,4498],{},[36,4491,4492],{},"write!",[36,4494,4495],{},"writeln!",[36,4497,2930],{}," when writing to a buffer.",[1139,4500,4501,4504],{},[36,4502,4503],{},"matches!"," for one-arm boolean checks.",[1139,4506,4507,4510],{},[36,4508,4509],{},"let-else"," for early-return validation.",[1139,4512,4513,4515],{},[36,4514,4208],{}," for borrowed-or-owned APIs.",[18,4517,4519],{"id":4518},"summary","Summary",[14,4521,4522,4523,4525,4526,1151,4528,1151,4530,4532,4533,4535,4536,4538],{},"Builder for complex construction. Newtype for type safety. Typestate for compile-time state machines. Traits for polymorphism (static via generics, dynamic via ",[36,4524,2309],{},"). RAII for resources. ",[36,4527,1150],{},[36,4529,3162],{},[36,4531,589],{}," for conversions. Iterators over loops. Avoid ",[36,4534,3986],{},", globals, and over-abstraction. Document with ",[36,4537,4107],{},". Use idiomatic naming and patterns.",[14,4540,4541],{},"Next: Performance, profiling, and optimization.",[4543,4544,4545],"style",{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#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);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}",{"title":34,"searchDepth":60,"depth":60,"links":4547},[4548,4551,4552,4553,4554,4555,4556,4557,4558,4559,4560,4561,4563,4565,4567,4568,4569,4570,4571,4572,4573,4574,4576,4577,4579,4580,4581,4582,4583,4585,4586,4587,4588],{"id":20,"depth":60,"text":21,"children":4549},[4550],{"id":763,"depth":75,"text":764},{"id":981,"depth":60,"text":982},{"id":1164,"depth":60,"text":1165},{"id":1479,"depth":60,"text":1480},{"id":1812,"depth":60,"text":1813},{"id":2117,"depth":60,"text":2118},{"id":2411,"depth":60,"text":2412},{"id":2607,"depth":60,"text":2608},{"id":2747,"depth":60,"text":2748},{"id":2855,"depth":60,"text":2856},{"id":2983,"depth":60,"text":2984},{"id":3063,"depth":60,"text":4562},"12. From\u002FInto for Conversions",{"id":3158,"depth":60,"text":4564},"13. AsRef\u002FAsMut for Flexible Borrowing",{"id":3277,"depth":60,"text":4566},"14. Error-Conversion via ?",{"id":3369,"depth":60,"text":3370},{"id":3444,"depth":60,"text":3445},{"id":3529,"depth":60,"text":3530},{"id":3631,"depth":60,"text":3632},{"id":3644,"depth":60,"text":3645},{"id":3651,"depth":60,"text":3652},{"id":3834,"depth":60,"text":3835},{"id":3849,"depth":60,"text":4575},"22. Use ? Liberally",{"id":3866,"depth":60,"text":3867},{"id":3982,"depth":60,"text":4578},"24. Avoid unwrap in Public Code",{"id":4006,"depth":60,"text":4007},{"id":4133,"depth":60,"text":4134},{"id":4172,"depth":60,"text":4173},{"id":4189,"depth":60,"text":4190},{"id":4204,"depth":60,"text":4584},"29. Cow for Borrowed-or-Owned",{"id":4340,"depth":60,"text":4341},{"id":4350,"depth":60,"text":4351},{"id":4446,"depth":60,"text":4447},{"id":4518,"depth":60,"text":4519},"md",{},"\u002Frust\u002F30-design-patterns",{"title":5,"description":16},"rust\u002F30-design-patterns","MNAydNIR7nLhBjuEyQAb9gxULBd0u1bVWeXhAqPZZ0U",1785944093279]