[{"data":1,"prerenderedAt":1651},["ShallowReactive",2],{"navigation":3,"\u002Fintegrations\u002Fweb\u002Ftonic":335,"\u002Fintegrations\u002Fweb\u002Ftonic-surround":1646},[4,27,73,95,121,135,305,331],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":26},"Getting started","i-lucide-rocket","\u002Fgetting-started","1.getting-started",[10,14,18,22],{"title":11,"path":12,"stem":13},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction",{"title":15,"path":16,"stem":17},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation",{"title":19,"path":20,"stem":21},"Quick start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F3.quick-start",{"title":23,"path":24,"stem":25},"MSRV","\u002Fgetting-started\u002Fmsrv","1.getting-started\u002F9.msrv",false,{"title":28,"icon":29,"path":30,"stem":31,"children":32,"page":26},"Schemas","i-lucide-shapes","\u002Fschemas","2.schemas",[33,37,41,45,49,53,57,61,65,69],{"title":34,"path":35,"stem":36},"Strings","\u002Fschemas\u002Fstrings","2.schemas\u002F1.strings",{"title":38,"path":39,"stem":40},"Custom rules","\u002Fschemas\u002Frules","2.schemas\u002F10.rules",{"title":42,"path":43,"stem":44},"Numbers","\u002Fschemas\u002Fnumbers","2.schemas\u002F2.numbers",{"title":46,"path":47,"stem":48},"Booleans, literals and enums","\u002Fschemas\u002Fprimitives","2.schemas\u002F3.primitives",{"title":50,"path":51,"stem":52},"Dates and times","\u002Fschemas\u002Fdates","2.schemas\u002F4.dates",{"title":54,"path":55,"stem":56},"Collections","\u002Fschemas\u002Fcollections","2.schemas\u002F5.collections",{"title":58,"path":59,"stem":60},"Dynamic objects","\u002Fschemas\u002Fobjects","2.schemas\u002F6.objects",{"title":62,"path":63,"stem":64},"Modifiers","\u002Fschemas\u002Fmodifiers","2.schemas\u002F7.modifiers",{"title":66,"path":67,"stem":68},"Combinators","\u002Fschemas\u002Fcombinators","2.schemas\u002F8.combinators",{"title":70,"path":71,"stem":72},"Other types","\u002Fschemas\u002Fspecial-types","2.schemas\u002F9.special-types",{"title":74,"icon":75,"path":76,"stem":77,"children":78,"page":26},"Structs","i-lucide-braces","\u002Fstructs","3.structs",[79,83,87,91],{"title":80,"path":81,"stem":82},"schema! macro","\u002Fstructs\u002Fschema-macro","3.structs\u002F1.schema-macro",{"title":84,"path":85,"stem":86},"#[derive(Validate)]","\u002Fstructs\u002Fderive","3.structs\u002F2.derive",{"title":88,"path":89,"stem":90},"Parse vs validate","\u002Fstructs\u002Fparse-vs-validate","3.structs\u002F3.parse-vs-validate",{"title":92,"path":93,"stem":94},"Lenient parsing","\u002Fstructs\u002Flenient","3.structs\u002F4.lenient",{"title":96,"icon":97,"path":98,"stem":99,"children":100,"page":26},"Errors","i-lucide-triangle-alert","\u002Ferrors","4.errors",[101,105,109,113,117],{"title":102,"path":103,"stem":104},"Error model","\u002Ferrors\u002Foverview","4.errors\u002F1.overview",{"title":106,"path":107,"stem":108},"Issue codes","\u002Ferrors\u002Fissue-codes","4.errors\u002F2.issue-codes",{"title":110,"path":111,"stem":112},"Formatting","\u002Ferrors\u002Fformatting","4.errors\u002F3.formatting",{"title":114,"path":115,"stem":116},"Custom messages","\u002Ferrors\u002Fcustom-messages","4.errors\u002F4.custom-messages",{"title":118,"path":119,"stem":120},"Translations","\u002Ferrors\u002Fi18n","4.errors\u002F5.i18n",{"title":122,"icon":123,"path":124,"stem":125,"children":126,"page":26},"OpenAPI","i-lucide-file-json","\u002Fopenapi","5.openapi",[127,131],{"title":128,"path":129,"stem":130},"JSON Schema and OpenAPI","\u002Fopenapi\u002Fjson-schema","5.openapi\u002F1.json-schema",{"title":132,"path":133,"stem":134},"Schema diff","\u002Fopenapi\u002Fdiff","5.openapi\u002F2.diff",{"title":136,"icon":137,"path":138,"stem":139,"children":140,"page":26},"Integrations","i-lucide-plug","\u002Fintegrations","6.integrations",[141,191,209,223,245,259,273,291],{"title":142,"icon":143,"path":144,"stem":145,"children":146,"page":26},"Web frameworks","i-lucide-globe","\u002Fintegrations\u002Fweb","6.integrations\u002F1.web",[147,151,155,159,163,167,171,175,179,183,187],{"title":148,"path":149,"stem":150},"Web adapters overview","\u002Fintegrations\u002Fweb\u002Foverview","6.integrations\u002F1.web\u002F01.overview",{"title":152,"path":153,"stem":154},"vld-axum","\u002Fintegrations\u002Fweb\u002Faxum","6.integrations\u002F1.web\u002F02.axum",{"title":156,"path":157,"stem":158},"vld-actix","\u002Fintegrations\u002Fweb\u002Factix","6.integrations\u002F1.web\u002F03.actix",{"title":160,"path":161,"stem":162},"vld-ntex","\u002Fintegrations\u002Fweb\u002Fntex","6.integrations\u002F1.web\u002F04.ntex",{"title":164,"path":165,"stem":166},"vld-poem","\u002Fintegrations\u002Fweb\u002Fpoem","6.integrations\u002F1.web\u002F05.poem",{"title":168,"path":169,"stem":170},"vld-rama","\u002Fintegrations\u002Fweb\u002Frama","6.integrations\u002F1.web\u002F06.rama",{"title":172,"path":173,"stem":174},"vld-rocket","\u002Fintegrations\u002Fweb\u002Frocket","6.integrations\u002F1.web\u002F07.rocket",{"title":176,"path":177,"stem":178},"vld-salvo","\u002Fintegrations\u002Fweb\u002Fsalvo","6.integrations\u002F1.web\u002F08.salvo",{"title":180,"path":181,"stem":182},"vld-tower","\u002Fintegrations\u002Fweb\u002Ftower","6.integrations\u002F1.web\u002F09.tower",{"title":184,"path":185,"stem":186},"vld-warp","\u002Fintegrations\u002Fweb\u002Fwarp","6.integrations\u002F1.web\u002F10.warp",{"title":188,"path":189,"stem":190},"vld-tonic","\u002Fintegrations\u002Fweb\u002Ftonic","6.integrations\u002F1.web\u002F11.tonic",{"title":192,"icon":193,"path":194,"stem":195,"children":196,"page":26},"OpenAPI and JSON Schema","i-lucide-file-code","\u002Fintegrations\u002Fopenapi","6.integrations\u002F2.openapi",[197,201,205],{"title":198,"path":199,"stem":200},"vld-utoipa","\u002Fintegrations\u002Fopenapi\u002Futoipa","6.integrations\u002F2.openapi\u002F1.utoipa",{"title":202,"path":203,"stem":204},"vld-schemars","\u002Fintegrations\u002Fopenapi\u002Fschemars","6.integrations\u002F2.openapi\u002F2.schemars",{"title":206,"path":207,"stem":208},"vld-aide","\u002Fintegrations\u002Fopenapi\u002Faide","6.integrations\u002F2.openapi\u002F3.aide",{"title":210,"icon":211,"path":212,"stem":213,"children":214,"page":26},"Codegen and test data","i-lucide-wand","\u002Fintegrations\u002Fcodegen","6.integrations\u002F3.codegen",[215,219],{"title":216,"path":217,"stem":218},"vld-ts","\u002Fintegrations\u002Fcodegen\u002Fts","6.integrations\u002F3.codegen\u002F1.ts",{"title":220,"path":221,"stem":222},"vld-fake","\u002Fintegrations\u002Fcodegen\u002Ffake","6.integrations\u002F3.codegen\u002F2.fake",{"title":224,"icon":225,"path":226,"stem":227,"children":228,"page":26},"Databases","i-lucide-database","\u002Fintegrations\u002Fdatabase","6.integrations\u002F4.database",[229,233,237,241],{"title":230,"path":231,"stem":232},"vld-sqlx","\u002Fintegrations\u002Fdatabase\u002Fsqlx","6.integrations\u002F4.database\u002F1.sqlx",{"title":234,"path":235,"stem":236},"vld-diesel","\u002Fintegrations\u002Fdatabase\u002Fdiesel","6.integrations\u002F4.database\u002F2.diesel",{"title":238,"path":239,"stem":240},"vld-sea","\u002Fintegrations\u002Fdatabase\u002Fsea-orm","6.integrations\u002F4.database\u002F3.sea-orm",{"title":242,"path":243,"stem":244},"vld-surrealdb","\u002Fintegrations\u002Fdatabase\u002Fsurrealdb","6.integrations\u002F4.database\u002F4.surrealdb",{"title":246,"icon":247,"path":248,"stem":249,"children":250,"page":26},"Messaging","i-lucide-mail","\u002Fintegrations\u002Fmessaging","6.integrations\u002F5.messaging",[251,255],{"title":252,"path":253,"stem":254},"vld-redis","\u002Fintegrations\u002Fmessaging\u002Fredis","6.integrations\u002F5.messaging\u002F1.redis",{"title":256,"path":257,"stem":258},"vld-lapin","\u002Fintegrations\u002Fmessaging\u002Flapin","6.integrations\u002F5.messaging\u002F2.lapin",{"title":260,"icon":261,"path":262,"stem":263,"children":264,"page":26},"Config and CLI","i-lucide-terminal","\u002Fintegrations\u002Fconfig-cli","6.integrations\u002F6.config-cli",[265,269],{"title":266,"path":267,"stem":268},"vld-config","\u002Fintegrations\u002Fconfig-cli\u002Fconfig","6.integrations\u002F6.config-cli\u002F1.config",{"title":270,"path":271,"stem":272},"vld-clap","\u002Fintegrations\u002Fconfig-cli\u002Fclap","6.integrations\u002F6.config-cli\u002F2.clap",{"title":274,"icon":275,"path":276,"stem":277,"children":278,"page":26},"UI frameworks","i-lucide-monitor","\u002Fintegrations\u002Fui","6.integrations\u002F7.ui",[279,283,287],{"title":280,"path":281,"stem":282},"vld-dioxus","\u002Fintegrations\u002Fui\u002Fdioxus","6.integrations\u002F7.ui\u002F1.dioxus",{"title":284,"path":285,"stem":286},"vld-leptos","\u002Fintegrations\u002Fui\u002Fleptos","6.integrations\u002F7.ui\u002F2.leptos",{"title":288,"path":289,"stem":290},"vld-tauri","\u002Fintegrations\u002Fui\u002Ftauri","6.integrations\u002F7.ui\u002F3.tauri",{"title":292,"icon":293,"path":294,"stem":295,"children":296,"page":26},"Shared crates","i-lucide-package","\u002Fintegrations\u002Fshared","6.integrations\u002F8.shared",[297,301],{"title":298,"path":299,"stem":300},"vld-http-common","\u002Fintegrations\u002Fshared\u002Fhttp-common","6.integrations\u002F8.shared\u002F1.http-common",{"title":302,"path":303,"stem":304},"vld-integration-common","\u002Fintegrations\u002Fshared\u002Fintegration-common","6.integrations\u002F8.shared\u002F2.integration-common",{"title":306,"icon":307,"path":308,"stem":309,"children":310,"page":26},"Guides","i-lucide-book-open","\u002Fguides","7.guides",[311,315,319,323,327],{"title":312,"path":313,"stem":314},"Migration","\u002Fguides\u002Fmigration","7.guides\u002F1.migration",{"title":316,"path":317,"stem":318},"Security notes","\u002Fguides\u002Fsecurity","7.guides\u002F2.security",{"title":320,"path":321,"stem":322},"Performance","\u002Fguides\u002Fperformance","7.guides\u002F3.performance",{"title":324,"path":325,"stem":326},"Contributing","\u002Fguides\u002Fcontributing","7.guides\u002F4.contributing",{"title":328,"path":329,"stem":330},"FAQ","\u002Fguides\u002Ffaq","7.guides\u002F5.faq",{"title":332,"path":333,"stem":334},"Changelog","\u002Fchangelog","9.changelog",{"id":336,"title":188,"body":337,"description":1632,"extension":1633,"links":1634,"meta":1643,"navigation":485,"path":189,"seo":1644,"stem":190,"__hash__":1645},"docs\u002F6.integrations\u002F1.web\u002F11.tonic.md",{"type":338,"value":339,"toc":1622},"minimark",[340,361,366,426,441,445,1005,1028,1033,1044,1083,1087,1251,1255,1416,1420,1430,1564,1579,1583,1618],[341,342,343,344,351,352,356,357,360],"p",{},"Validation helpers for ",[345,346,350],"a",{"href":347,"rel":348},"https:\u002F\u002Fdocs.rs\u002Ftonic",[349],"nofollow","tonic"," gRPC services: attach rules to prost messages, validate request metadata, and turn failures into ",[353,354,355],"code",{},"Status::invalid_argument",". Only ",[353,358,359],{},"tonic::{Request, Status}"," are used, so no tonic transport features are needed.",[362,363,365],"h2",{"id":364},"install","Install",[367,368,374],"pre",{"className":369,"code":370,"filename":371,"language":372,"meta":373,"style":373},"language-toml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","[dependencies]\nvld = \"0.5\"\nvld-tonic = \"0.5\"\n","Cargo.toml","toml","",[353,375,376,392,412],{"__ignoreMap":373},[377,378,381,385,389],"span",{"class":379,"line":380},"line",1,[377,382,384],{"class":383},"sMK4o","[",[377,386,388],{"class":387},"sBMFI","dependencies",[377,390,391],{"class":383},"]\n",[377,393,395,399,402,405,409],{"class":379,"line":394},2,[377,396,398],{"class":397},"sTEyZ","vld ",[377,400,401],{"class":383},"=",[377,403,404],{"class":383}," \"",[377,406,408],{"class":407},"sfazB","0.5",[377,410,411],{"class":383},"\"\n",[377,413,415,418,420,422,424],{"class":379,"line":414},3,[377,416,417],{"class":397},"vld-tonic ",[377,419,401],{"class":383},[377,421,404],{"class":383},[377,423,408],{"class":407},[377,425,411],{"class":383},[341,427,428,429,432,433,437,438,440],{},"The dependency is ",[353,430,431],{},"tonic >=0.12, \u003C0.15","; there are no version features. MSRV ",[434,435,436],"strong",{},"1.85",", see ",[345,439,23],{"href":24},".",[362,442,444],{"id":443},"example","Example",[367,446,450],{"className":447,"code":448,"language":449,"meta":373,"style":373},"language-rust shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","use tonic::{Request, Response, Status};\n\n\u002F\u002F Generated by prost; vld needs no extra derives.\n#[derive(Clone, PartialEq, prost::Message)]\npub struct CreateUserRequest {\n    #[prost(string, tag = \"1\")]\n    pub name: String,\n    #[prost(string, tag = \"2\")]\n    pub email: String,\n}\n\nvld_tonic::impl_validate!(CreateUserRequest {\n    name  => vld::string().min(2).max(100),\n    email => vld::string().email(),\n});\n\nvld::schema! {\n    #[derive(Debug, Clone)]\n    pub struct AuthMeta {\n        pub authorization: String => vld::string().starts_with(\"Bearer \"),\n    }\n}\n\nasync fn create_user(request: Request\u003CCreateUserRequest>) -> Result\u003CResponse\u003C()>, Status> {\n    let auth: AuthMeta = vld_tonic::validate_metadata(&request)?;\n    let msg = vld_tonic::validate(request)?; \u002F\u002F Status::invalid_argument on failure\n    println!(\"{} by {}\", msg.name, auth.authorization);\n    Ok(Response::new(()))\n}\n","rust",[353,451,452,481,487,493,527,543,574,592,618,632,638,643,662,702,724,730,735,748,767,779,817,823,828,833,884,916,943,982,1000],{"__ignoreMap":373},[377,453,454,458,461,464,467,470,473,475,478],{"class":379,"line":380},[377,455,457],{"class":456},"sbssI","use",[377,459,460],{"class":387}," tonic",[377,462,463],{"class":383},"::{",[377,465,466],{"class":387},"Request",[377,468,469],{"class":383},",",[377,471,472],{"class":387}," Response",[377,474,469],{"class":383},[377,476,477],{"class":387}," Status",[377,479,480],{"class":383},"};\n",[377,482,483],{"class":379,"line":394},[377,484,486],{"emptyLinePlaceholder":485},true,"\n",[377,488,489],{"class":379,"line":414},[377,490,492],{"class":491},"sHwdD","\u002F\u002F Generated by prost; vld needs no extra derives.\n",[377,494,496,499,502,505,508,510,513,515,518,521,524],{"class":379,"line":495},4,[377,497,498],{"class":383},"#[",[377,500,501],{"class":397},"derive",[377,503,504],{"class":383},"(",[377,506,507],{"class":387},"Clone",[377,509,469],{"class":383},[377,511,512],{"class":387}," PartialEq",[377,514,469],{"class":383},[377,516,517],{"class":397}," prost",[377,519,520],{"class":383},"::",[377,522,523],{"class":387},"Message",[377,525,526],{"class":383},")]\n",[377,528,530,534,537,540],{"class":379,"line":529},5,[377,531,533],{"class":532},"spNyl","pub",[377,535,536],{"class":532}," struct",[377,538,539],{"class":387}," CreateUserRequest",[377,541,542],{"class":383}," {\n",[377,544,546,549,552,554,557,559,562,564,566,569,572],{"class":379,"line":545},6,[377,547,548],{"class":383},"    #[",[377,550,551],{"class":397},"prost",[377,553,504],{"class":383},[377,555,556],{"class":397},"string",[377,558,469],{"class":383},[377,560,561],{"class":397}," tag ",[377,563,401],{"class":383},[377,565,404],{"class":383},[377,567,568],{"class":407},"1",[377,570,571],{"class":383},"\"",[377,573,526],{"class":383},[377,575,577,580,583,586,589],{"class":379,"line":576},7,[377,578,579],{"class":532},"    pub",[377,581,582],{"class":397}," name",[377,584,585],{"class":383},":",[377,587,588],{"class":387}," String",[377,590,591],{"class":383},",\n",[377,593,595,597,599,601,603,605,607,609,611,614,616],{"class":379,"line":594},8,[377,596,548],{"class":383},[377,598,551],{"class":397},[377,600,504],{"class":383},[377,602,556],{"class":397},[377,604,469],{"class":383},[377,606,561],{"class":397},[377,608,401],{"class":383},[377,610,404],{"class":383},[377,612,613],{"class":407},"2",[377,615,571],{"class":383},[377,617,526],{"class":383},[377,619,621,623,626,628,630],{"class":379,"line":620},9,[377,622,579],{"class":532},[377,624,625],{"class":397}," email",[377,627,585],{"class":383},[377,629,588],{"class":387},[377,631,591],{"class":383},[377,633,635],{"class":379,"line":634},10,[377,636,637],{"class":383},"}\n",[377,639,641],{"class":379,"line":640},11,[377,642,486],{"emptyLinePlaceholder":485},[377,644,646,649,651,655,657,660],{"class":379,"line":645},12,[377,647,648],{"class":387},"vld_tonic",[377,650,520],{"class":383},[377,652,654],{"class":653},"s2Zo4","impl_validate!",[377,656,504],{"class":383},[377,658,659],{"class":387},"CreateUserRequest",[377,661,542],{"class":383},[377,663,665,668,671,674,676,678,681,684,686,688,691,694,696,699],{"class":379,"line":664},13,[377,666,667],{"class":397},"    name  ",[377,669,670],{"class":383},"=>",[377,672,673],{"class":387}," vld",[377,675,520],{"class":383},[377,677,556],{"class":653},[377,679,680],{"class":383},"().",[377,682,683],{"class":653},"min",[377,685,504],{"class":383},[377,687,613],{"class":456},[377,689,690],{"class":383},").",[377,692,693],{"class":653},"max",[377,695,504],{"class":383},[377,697,698],{"class":456},"100",[377,700,701],{"class":383},"),\n",[377,703,705,708,710,712,714,716,718,721],{"class":379,"line":704},14,[377,706,707],{"class":397},"    email ",[377,709,670],{"class":383},[377,711,673],{"class":387},[377,713,520],{"class":383},[377,715,556],{"class":653},[377,717,680],{"class":383},[377,719,720],{"class":653},"email",[377,722,723],{"class":383},"(),\n",[377,725,727],{"class":379,"line":726},15,[377,728,729],{"class":383},"});\n",[377,731,733],{"class":379,"line":732},16,[377,734,486],{"emptyLinePlaceholder":485},[377,736,738,741,743,746],{"class":379,"line":737},17,[377,739,740],{"class":387},"vld",[377,742,520],{"class":383},[377,744,745],{"class":653},"schema!",[377,747,542],{"class":383},[377,749,751,753,755,757,760,762,765],{"class":379,"line":750},18,[377,752,548],{"class":383},[377,754,501],{"class":397},[377,756,504],{"class":383},[377,758,759],{"class":387},"Debug",[377,761,469],{"class":383},[377,763,764],{"class":387}," Clone",[377,766,526],{"class":383},[377,768,770,772,774,777],{"class":379,"line":769},19,[377,771,579],{"class":532},[377,773,536],{"class":532},[377,775,776],{"class":387}," AuthMeta",[377,778,542],{"class":383},[377,780,782,785,788,790,792,795,797,799,801,803,806,808,810,813,815],{"class":379,"line":781},20,[377,783,784],{"class":532},"        pub",[377,786,787],{"class":397}," authorization",[377,789,585],{"class":383},[377,791,588],{"class":387},[377,793,794],{"class":383}," =>",[377,796,673],{"class":387},[377,798,520],{"class":383},[377,800,556],{"class":653},[377,802,680],{"class":383},[377,804,805],{"class":653},"starts_with",[377,807,504],{"class":383},[377,809,571],{"class":383},[377,811,812],{"class":407},"Bearer ",[377,814,571],{"class":383},[377,816,701],{"class":383},[377,818,820],{"class":379,"line":819},21,[377,821,822],{"class":383},"    }\n",[377,824,826],{"class":379,"line":825},22,[377,827,637],{"class":383},[377,829,831],{"class":379,"line":830},23,[377,832,486],{"emptyLinePlaceholder":485},[377,834,836,839,842,845,847,850,852,855,858,860,863,866,869,871,874,877,879,882],{"class":379,"line":835},24,[377,837,838],{"class":456},"async",[377,840,841],{"class":456}," fn",[377,843,844],{"class":653}," create_user",[377,846,504],{"class":383},[377,848,849],{"class":397},"request",[377,851,585],{"class":383},[377,853,854],{"class":387}," Request",[377,856,857],{"class":383},"\u003C",[377,859,659],{"class":387},[377,861,862],{"class":383},">)",[377,864,865],{"class":383}," ->",[377,867,868],{"class":387}," Result",[377,870,857],{"class":383},[377,872,873],{"class":387},"Response",[377,875,876],{"class":383},"\u003C()>,",[377,878,477],{"class":387},[377,880,881],{"class":383},">",[377,883,542],{"class":383},[377,885,887,890,893,895,897,900,903,905,908,911,913],{"class":379,"line":886},25,[377,888,889],{"class":532},"    let",[377,891,892],{"class":397}," auth",[377,894,585],{"class":383},[377,896,776],{"class":387},[377,898,899],{"class":383}," =",[377,901,902],{"class":387}," vld_tonic",[377,904,520],{"class":383},[377,906,907],{"class":653},"validate_metadata",[377,909,910],{"class":383},"(&",[377,912,849],{"class":397},[377,914,915],{"class":383},")?;\n",[377,917,919,921,924,926,928,930,933,935,937,940],{"class":379,"line":918},26,[377,920,889],{"class":532},[377,922,923],{"class":397}," msg ",[377,925,401],{"class":383},[377,927,902],{"class":387},[377,929,520],{"class":383},[377,931,932],{"class":653},"validate",[377,934,504],{"class":383},[377,936,849],{"class":397},[377,938,939],{"class":383},")?;",[377,941,942],{"class":491}," \u002F\u002F Status::invalid_argument on failure\n",[377,944,946,949,951,954,957,960,962,965,967,970,972,974,976,979],{"class":379,"line":945},27,[377,947,948],{"class":653},"    println!",[377,950,504],{"class":383},[377,952,953],{"class":383},"\"{}",[377,955,956],{"class":407}," by ",[377,958,959],{"class":383},"{}\"",[377,961,469],{"class":383},[377,963,964],{"class":397}," msg",[377,966,440],{"class":383},[377,968,969],{"class":397},"name",[377,971,469],{"class":383},[377,973,892],{"class":397},[377,975,440],{"class":383},[377,977,978],{"class":397},"authorization",[377,980,981],{"class":383},");\n",[377,983,985,988,990,992,994,997],{"class":379,"line":984},28,[377,986,987],{"class":387},"    Ok",[377,989,504],{"class":383},[377,991,873],{"class":387},[377,993,520],{"class":383},[377,995,996],{"class":653},"new",[377,998,999],{"class":383},"(()))\n",[377,1001,1003],{"class":379,"line":1002},29,[377,1004,637],{"class":383},[341,1006,1007,1009,1010,1015,1016,1019,1020,1023,1024,1027],{},[353,1008,654],{}," builds on ",[345,1011,1012],{"href":81},[353,1013,1014],{},"vld::impl_rules!",": it adds inherent ",[353,1017,1018],{},"validate()"," \u002F ",[353,1021,1022],{},"is_valid()"," methods and implements ",[353,1025,1026],{},"VldMessage",". Each listed field is serialized with serde and checked by its schema.",[1029,1030,1032],"h3",{"id":1031},"validate-against-a-separate-schema","Validate against a separate schema",[341,1034,1035,1036,1039,1040,1043],{},"When a ",[353,1037,1038],{},"vld::schema!"," struct mirrors the message, validate a ",[353,1041,1042],{},"serde::Serialize"," message against it:",[367,1045,1047],{"className":447,"code":1046,"language":449,"meta":373,"style":373},"let msg = vld_tonic::validate_with::\u003CUserSchema, _>(request)?;\n",[353,1048,1049],{"__ignoreMap":373},[377,1050,1051,1054,1056,1058,1060,1062,1065,1068,1071,1073,1076,1079,1081],{"class":379,"line":380},[377,1052,1053],{"class":532},"let",[377,1055,923],{"class":397},[377,1057,401],{"class":383},[377,1059,902],{"class":387},[377,1061,520],{"class":383},[377,1063,1064],{"class":653},"validate_with",[377,1066,1067],{"class":383},"::\u003C",[377,1069,1070],{"class":387},"UserSchema",[377,1072,469],{"class":383},[377,1074,1075],{"class":397}," _",[377,1077,1078],{"class":383},">(",[377,1080,849],{"class":397},[377,1082,915],{"class":383},[1029,1084,1086],{"id":1085},"metadata-interceptor","Metadata interceptor",[367,1088,1090],{"className":447,"code":1089,"language":449,"meta":373,"style":373},"Server::builder()\n    .add_service(MyServiceServer::with_interceptor(\n        my_service,\n        vld_tonic::metadata_interceptor::\u003CAuthMeta>,\n    ))\n    .serve(addr)\n    .await?;\n\n\u002F\u002F In the handler:\nlet auth = vld_tonic::validated_metadata::\u003CAuthMeta, _>(&request)\n    .ok_or_else(|| Status::unauthenticated(\"missing auth\"))?;\n",[353,1091,1092,1105,1126,1133,1151,1156,1171,1182,1186,1191,1222],{"__ignoreMap":373},[377,1093,1094,1097,1099,1102],{"class":379,"line":380},[377,1095,1096],{"class":387},"Server",[377,1098,520],{"class":383},[377,1100,1101],{"class":653},"builder",[377,1103,1104],{"class":383},"()\n",[377,1106,1107,1110,1113,1115,1118,1120,1123],{"class":379,"line":394},[377,1108,1109],{"class":383},"    .",[377,1111,1112],{"class":653},"add_service",[377,1114,504],{"class":383},[377,1116,1117],{"class":387},"MyServiceServer",[377,1119,520],{"class":383},[377,1121,1122],{"class":653},"with_interceptor",[377,1124,1125],{"class":383},"(\n",[377,1127,1128,1131],{"class":379,"line":414},[377,1129,1130],{"class":397},"        my_service",[377,1132,591],{"class":383},[377,1134,1135,1138,1140,1143,1145,1148],{"class":379,"line":495},[377,1136,1137],{"class":387},"        vld_tonic",[377,1139,520],{"class":383},[377,1141,1142],{"class":387},"metadata_interceptor",[377,1144,1067],{"class":383},[377,1146,1147],{"class":387},"AuthMeta",[377,1149,1150],{"class":383},">,\n",[377,1152,1153],{"class":379,"line":529},[377,1154,1155],{"class":383},"    ))\n",[377,1157,1158,1160,1163,1165,1168],{"class":379,"line":545},[377,1159,1109],{"class":383},[377,1161,1162],{"class":653},"serve",[377,1164,504],{"class":383},[377,1166,1167],{"class":397},"addr",[377,1169,1170],{"class":383},")\n",[377,1172,1173,1175,1179],{"class":379,"line":576},[377,1174,1109],{"class":383},[377,1176,1178],{"class":1177},"s7zQu","await",[377,1180,1181],{"class":383},"?;\n",[377,1183,1184],{"class":379,"line":594},[377,1185,486],{"emptyLinePlaceholder":485},[377,1187,1188],{"class":379,"line":620},[377,1189,1190],{"class":491},"\u002F\u002F In the handler:\n",[377,1192,1193,1195,1198,1200,1202,1204,1207,1209,1211,1213,1215,1218,1220],{"class":379,"line":634},[377,1194,1053],{"class":532},[377,1196,1197],{"class":397}," auth ",[377,1199,401],{"class":383},[377,1201,902],{"class":387},[377,1203,520],{"class":383},[377,1205,1206],{"class":653},"validated_metadata",[377,1208,1067],{"class":383},[377,1210,1147],{"class":387},[377,1212,469],{"class":383},[377,1214,1075],{"class":397},[377,1216,1217],{"class":383},">(&",[377,1219,849],{"class":397},[377,1221,1170],{"class":383},[377,1223,1224,1226,1229,1232,1234,1236,1239,1241,1243,1246,1248],{"class":379,"line":640},[377,1225,1109],{"class":383},[377,1227,1228],{"class":653},"ok_or_else",[377,1230,1231],{"class":383},"(||",[377,1233,477],{"class":387},[377,1235,520],{"class":383},[377,1237,1238],{"class":653},"unauthenticated",[377,1240,504],{"class":383},[377,1242,571],{"class":383},[377,1244,1245],{"class":407},"missing auth",[377,1247,571],{"class":383},[377,1249,1250],{"class":383},"))?;\n",[362,1252,1254],{"id":1253},"api","API",[1256,1257,1258,1271],"table",{},[1259,1260,1261],"thead",{},[1262,1263,1264,1268],"tr",{},[1265,1266,1267],"th",{},"Item",[1265,1269,1270],{},"Purpose",[1272,1273,1274,1287,1299,1314,1333,1346,1359,1372,1384,1403],"tbody",{},[1262,1275,1276,1282],{},[1277,1278,1279],"td",{},[353,1280,1281],{},"impl_validate!(Type { field => schema, .. })",[1277,1283,1284,1285],{},"Attach rules to a message, implement ",[353,1286,1026],{},[1262,1288,1289,1293],{},[1277,1290,1291],{},[353,1292,1026],{},[1277,1294,1295,1296],{},"Trait with ",[353,1297,1298],{},"vld_validate(&self) -> Result\u003C(), VldError>",[1262,1300,1301,1309],{},[1277,1302,1303,1019,1306],{},[353,1304,1305],{},"validate(request)",[353,1307,1308],{},"validate_ref(&msg)",[1277,1310,1311,1312],{},"Validate a ",[353,1313,1026],{},[1262,1315,1316,1324],{},[1277,1317,1318,1019,1321],{},[353,1319,1320],{},"validate_with::\u003CS, _>(request)",[353,1322,1323],{},"validate_with_ref::\u003CS, _>(&msg)",[1277,1325,1311,1326,1329,1330],{},[353,1327,1328],{},"Serialize"," message against schema ",[353,1331,1332],{},"S",[1262,1334,1335,1340],{},[1277,1336,1337],{},[353,1338,1339],{},"validate_metadata::\u003CT, _>(&request)",[1277,1341,1342,1343],{},"Parse metadata into ",[353,1344,1345],{},"T",[1262,1347,1348,1353],{},[1277,1349,1350],{},[353,1351,1352],{},"metadata_interceptor::\u003CT>",[1277,1354,1355,1356],{},"Interceptor that validates metadata and stores ",[353,1357,1358],{},"Validated\u003CT>",[1262,1360,1361,1366],{},[1277,1362,1363],{},[353,1364,1365],{},"validated_metadata::\u003CT, _>(&request)",[1277,1367,1368,1371],{},[353,1369,1370],{},"Option\u003CT>"," stored by the interceptor",[1262,1373,1374,1378],{},[1277,1375,1376],{},[353,1377,1358],{},[1277,1379,1380,1381,1383],{},"Extension wrapper (derefs to ",[353,1382,1345],{},")",[1262,1385,1386,1394],{},[1277,1387,1388,1019,1391],{},[353,1389,1390],{},"vld_status(&err)",[353,1392,1393],{},"vld_status_with_code(&err, code)",[1277,1395,1396,1399,1400],{},[353,1397,1398],{},"VldError"," to ",[353,1401,1402],{},"Status",[1262,1404,1405,1410],{},[1277,1406,1407],{},[353,1408,1409],{},"prelude",[1277,1411,1412,1413],{},"All of the above plus ",[353,1414,1415],{},"vld::prelude::*",[362,1417,1419],{"id":1418},"status-format","Status format",[341,1421,1422,1425,1426,1429],{},[353,1423,1424],{},"vld_status"," returns ",[353,1427,1428],{},"Code::InvalidArgument"," with a JSON message:",[367,1431,1435],{"className":1432,"code":1433,"language":1434,"meta":373,"style":373},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"error\": \"VALIDATION_ERROR\",\n  \"message\": \"Request validation failed\",\n  \"details\": [\n    { \"path\": \".name\", \"message\": \"String must be at least 2 characters\", \"code\": \"too_small\" }\n  ]\n}\n","json",[353,1436,1437,1442,1463,1483,1497,1555,1560],{"__ignoreMap":373},[377,1438,1439],{"class":379,"line":380},[377,1440,1441],{"class":383},"{\n",[377,1443,1444,1447,1450,1452,1454,1456,1459,1461],{"class":379,"line":394},[377,1445,1446],{"class":383},"  \"",[377,1448,1449],{"class":532},"error",[377,1451,571],{"class":383},[377,1453,585],{"class":383},[377,1455,404],{"class":383},[377,1457,1458],{"class":407},"VALIDATION_ERROR",[377,1460,571],{"class":383},[377,1462,591],{"class":383},[377,1464,1465,1467,1470,1472,1474,1476,1479,1481],{"class":379,"line":414},[377,1466,1446],{"class":383},[377,1468,1469],{"class":532},"message",[377,1471,571],{"class":383},[377,1473,585],{"class":383},[377,1475,404],{"class":383},[377,1477,1478],{"class":407},"Request validation failed",[377,1480,571],{"class":383},[377,1482,591],{"class":383},[377,1484,1485,1487,1490,1492,1494],{"class":379,"line":495},[377,1486,1446],{"class":383},[377,1488,1489],{"class":532},"details",[377,1491,571],{"class":383},[377,1493,585],{"class":383},[377,1495,1496],{"class":383}," [\n",[377,1498,1499,1502,1504,1507,1509,1511,1513,1516,1518,1520,1522,1524,1526,1528,1530,1533,1535,1537,1539,1541,1543,1545,1547,1550,1552],{"class":379,"line":529},[377,1500,1501],{"class":383},"    {",[377,1503,404],{"class":383},[377,1505,1506],{"class":387},"path",[377,1508,571],{"class":383},[377,1510,585],{"class":383},[377,1512,404],{"class":383},[377,1514,1515],{"class":407},".name",[377,1517,571],{"class":383},[377,1519,469],{"class":383},[377,1521,404],{"class":383},[377,1523,1469],{"class":387},[377,1525,571],{"class":383},[377,1527,585],{"class":383},[377,1529,404],{"class":383},[377,1531,1532],{"class":407},"String must be at least 2 characters",[377,1534,571],{"class":383},[377,1536,469],{"class":383},[377,1538,404],{"class":383},[377,1540,353],{"class":387},[377,1542,571],{"class":383},[377,1544,585],{"class":383},[377,1546,404],{"class":383},[377,1548,1549],{"class":407},"too_small",[377,1551,571],{"class":383},[377,1553,1554],{"class":383}," }\n",[377,1556,1557],{"class":379,"line":545},[377,1558,1559],{"class":383},"  ]\n",[377,1561,1562],{"class":379,"line":576},[377,1563,637],{"class":383},[341,1565,1566,1568,1569,1572,1573,1575,1576,440],{},[353,1567,1506],{}," uses the same format as the HTTP adapters (",[353,1570,1571],{},".user.items[0].name","); ",[353,1574,353],{}," is ",[353,1577,1578],{},"IssueCode::key()",[362,1580,1582],{"id":1581},"gotchas","Gotchas",[1584,1585,1586,1610],"ul",{},[1587,1588,1589,1590,1593,1594,1597,1598,1601,1602,1605,1606,1609],"li",{},"Metadata keys follow the header rules: ",[353,1591,1592],{},"x-request-id"," becomes ",[353,1595,1596],{},"x_request_id",", keys that already contain ",[353,1599,1600],{},"_"," are ignored, binary (",[353,1603,1604],{},"-bin",") keys are skipped. Values are coerced (",[353,1607,1608],{},"\"42\""," is a number, but a string field still accepts it).",[1587,1611,1612,1614,1615,440],{},[353,1613,1064],{}," serializes the message first; a serialization failure is ",[353,1616,1617],{},"Status::internal",[1619,1620,1621],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}",{"title":373,"searchDepth":394,"depth":414,"links":1623},[1624,1625,1629,1630,1631],{"id":364,"depth":394,"text":365},{"id":443,"depth":394,"text":444,"children":1626},[1627,1628],{"id":1031,"depth":414,"text":1032},{"id":1085,"depth":414,"text":1086},{"id":1253,"depth":394,"text":1254},{"id":1418,"depth":394,"text":1419},{"id":1581,"depth":394,"text":1582},"Validate tonic gRPC messages and metadata with vld schemas.","md",[1635,1640],{"label":1636,"icon":1637,"to":1638,"target":1639},"crates.io","i-simple-icons-rust","https:\u002F\u002Fcrates.io\u002Fcrates\u002Fvld-tonic","_blank",{"label":1641,"icon":307,"to":1642,"target":1639},"docs.rs","https:\u002F\u002Fdocs.rs\u002Fvld-tonic",{},{"title":188,"description":1632},"Ec4HE4QP_CjFqm7ne-uMpUr7znyIF8tUprL0N2MUNzU",[1647,1649],{"title":184,"path":185,"stem":186,"description":1648,"children":-1},"Warp filters that validate request data with vld schemas, plus a JSON rejection handler.",{"title":198,"path":199,"stem":200,"description":1650,"children":-1},"Use vld schemas as utoipa ToSchema \u002F IntoParams types, so validation rules and OpenAPI docs come from one definition.",1794036361815]