рдЬрдВрдЧ рдореЗрдВ рд╕рд╛рдорд╛рдиреНрдп рддрд░реАрдХреЗ: рдХреИрд╕реЗ рдПрдХреНрд╕реЛрдирдо рдХреЛ рд▓реЛрд╣реЗ рд╕реЗ рдПрдХреНрдЯрд┐рдХреНрд╕-рд╡реЗрдм рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛

рдЬрдВрдЧ рдкрд╛рд░рд┐рд╕реНрдерд┐рддрд┐рдХреА рддрдВрддреНрд░ рдЕрднреА рднреА рдмрдврд╝ рд░рд╣рд╛ рд╣реИред рдирддреАрдЬрддрди, рдмреЗрд╣рддрд░ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╡рд╛рд▓реЗ рдирдП рдкреБрд╕реНрддрдХрд╛рд▓рдп рдЕрдХреНрд╕рд░ рдбреЗрд╡рд▓рдкрд░ рд╕рдореБрджрд╛рдп рдореЗрдВ рдЬрд╛рд░реА рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдЬрдмрдХрд┐ рдкреБрд░рд╛рдиреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдЕрдкреНрд░рдЪрд▓рд┐рдд рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред рдЬрдм рд╣рдордиреЗ рд╢реБрд░реВ рдореЗрдВ рдПрдХреНрд╕реЛрдирдо рдбрд┐рдЬрд╛рдЗрди рдХрд┐рдпрд╛, рддреЛ рд╣рдордиреЗ рдЖрдпрд░рди рд╡реЗрдм-рдлреНрд░реЗрдорд╡рд░реНрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рд╣рдо рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдЬреЗрдиреЗрд░рд┐рдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╣рдордиреЗ рдПрдХреНрдЬрд╝реЛрдирдо рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛ рдПрдХреНрдЯрд┐рдХреНрд╕-рд╡реЗрдм рдкрд░ рдХреИрд╕реЗ рдкреЛрд░реНрдЯ рдХрд┐рдпрд╛ред



рд▓реЛрд╣реЗ рдкрд░ рдПрдХреНрд╕реЛрдирдо


рдПрдХреНрд╕реЛрдирдо рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рдореЗрдВ, рд▓реЛрд╣реЗ рдХреЗ рдврд╛рдВрдЪреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдмрд┐рдирд╛ рдХрд┐рд╕реА рд╕рд╛рд░ рдХреЗ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд╣рдордиреЗ рдХреБрдЫ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЗ рд▓рд┐рдП рд╣реИрдВрдбрд▓рд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдП рдФрд░ рд╕рд╣рд╛рдпрдХ рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ URL рдкрд╛рд░реНрд╕ рдХрд░рдХреЗ рдЕрдиреБрд░реЛрдз рдкреИрд░рд╛рдореАрдЯрд░ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдП; рдкрд░рд┐рдгрд╛рдо рдХреЗрд╡рд▓ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд╛рдкрд╕ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред

рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреА рддрд░рд╣ рджреЗрдЦрд╛ рдЧрдпрд╛ (рд▓рдЧрднрдЧ):

fn set_blocks_response(self, router: &mut Router) { let blocks = move |req: &mut Request| -> IronResult<Response> { let count: usize = self.required_param(req, "count")?; let latest: Option<u64> = self.optional_param(req, "latest")?; let skip_empty_blocks: bool = self.optional_param(req, "skip_empty_blocks")? .unwrap_or(false); let info = self.blocks(count, latest.map(Height), skip_empty_blocks)?; self.ok_response(&::serde_json::to_value(info).unwrap()) }; router.get("/v1/blocks", blocks, "blocks"); } 

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдордиреЗ рдХреЙрд░реНрд╕ рд╣реЗрдбрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдХреБрдЫ рдорд┐рдбрд▓рд╡реЗрдпрд░ рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред рд╣рдордиреЗ рд╕рднреА рд╣реИрдВрдбрд▓рд░ рдХреЛ рдПрдХ рд╣реА рдПрдкреАрдЖрдИ рдореЗрдВ рдорд░реНрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдорд╛рдЙрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИред

рдЖрдпрд░рди рд╕реЗ рджреВрд░ рд╢рд┐рдлреНрдЯ рдХрд░рдиреЗ рдХрд╛ рд╣рдорд╛рд░рд╛ рдирд┐рд░реНрдгрдп


рдЖрдпрд░рди рдПрдХ рдЕрдЪреНрдЫрд╛ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдерд╛, рдЬрд┐рд╕рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдкреНрд▓рдЧрдЗрдиреНрд╕ рдереЗред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрд╣ рдЙрди рджрд┐рдиреЛрдВ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛ рдЬрдм рд╡рд╛рдпрджрд╛ рдФрд░ рддреЛрдХрд┐рдпреЛ рдЬреИрд╕реА рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдБ рдореМрдЬреВрдж рдирд╣реАрдВ рдереАрдВред

рдЖрдпрд░рди рдХреА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдореЗрдВ рд╕рдордХрд╛рд▓рд┐рдХ рдЕрдиреБрд░реЛрдз рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд╢рд╛рдорд┐рд▓ рд╣реИ, рдЬреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рдПрдХ рд╕рд╛рде рдЦреБрд▓реЗ рдХрдиреЗрдХреНрд╢рдиреЛрдВ рдХреА рдПрдХ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рд╕реЗ рдкреНрд░рднрд╛рд╡рд┐рдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╕реНрдХреЗрд▓реЗрдмрд▓ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдпрд░рди рдХреЛ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдмрдирдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдкреВрд░реЗ рдврд╛рдВрдЪреЗ рдХреЛ рдкреБрдирд░реНрд▓реЗрдЦрди рдФрд░ рдкреБрдирд░реНрд▓реЗрдЦрди рдХрд░рдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реЛрддрд╛ рд╣реИред рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╣рдордиреЗ рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдЗрдВрдЬреАрдирд┐рдпрд░реЛрдВ рджреНрд╡рд╛рд░рд╛ рдЖрдпрд░рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдПрдХ рдХреНрд░рдорд┐рдХ рдкреНрд░рд╕реНрдерд╛рди рджреЗрдЦрд╛ рд╣реИред

рд╡реНрд╣рд╛рдИ рд╡реА рдЪреЛрдЬ рдПрдХреНрдЯрд┐рдХреНрд╕-рд╡реЗрдм


рдПрдХреНрдЯрд┐рдХреНрд╕-рд╡реЗрдм рдПрдХ рд▓реЛрдХрдкреНрд░рд┐рдп рдврд╛рдВрдЪрд╛ рд╣реИ рдЬреЛ TechEmpower рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдкрд░ рдЙрдЪреНрдЪ рд╕реНрдерд╛рди рдкрд░ рд╣реИред рдЗрд╕рдореЗрдВ рдЖрдпрд░рди рдХреЗ рд╡рд┐рдкрд░реАрдд рдПрдХ рд╕рдХреНрд░рд┐рдп рдбреЗрд╡рд▓рдкрд░ рд╕рдореБрджрд╛рдп рд╣реИ, рдФрд░ рдЗрд╕рдореЗрдВ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдПрдкреАрдЖрдИ рдФрд░ рдЙрдЪреНрдЪ-рдЧреБрдгрд╡рддреНрддрд╛ рд╡рд╛рд▓рд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдПрдХреНрдЯрд┐рдХреНрд╕ рдЕрднрд┐рдиреЗрддрд╛ рдврд╛рдВрдЪреЗ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╣реИред рдЕрдиреБрд░реЛрдз рдереНрд░реЗрдб рдкреВрд▓ рджреНрд╡рд╛рд░рд╛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд░реВрдк рд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ; рдпрджрд┐ рдкреИрдирд┐рдХ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЕрднрд┐рдиреЗрддрд╛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдкреБрдирд░рд╛рд░рдВрдн рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

рдкрд╣рд▓реЗ, рдЪрд┐рдВрддрд╛рдПрдБ рдЙрдард╛рдИ рдЧрдИрдВ рдХрд┐ рдПрдХреНрдЯрд┐рдХреНрд╕-рд╡реЗрдм рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдЕрд╕реБрд░рдХреНрд╖рд┐рдд рдХреЛрдб рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЕрд╕реБрд░рдХреНрд╖рд┐рдд рдХреЛрдб рдХреА рдорд╛рддреНрд░рд╛ рдХрд╛рдлреА рдХрдо рд╣реЛ рдЧрдИ рдереА рдЬрдм рдПрдХ рд╕реБрд░рдХреНрд╖рд┐рдд рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ - рд░рд╕реНрдЯ рдореЗрдВ рд░реВрдкрд░реЗрдЦрд╛ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛ред рдмрд┐рдЯрдлреНрдпреВрд░реА рдХреЗ рдЗрдВрдЬреАрдирд┐рдпрд░реЛрдВ рдиреЗ рд╕реНрд╡рдпрдВ рдЗрд╕ рдХреЛрдб рдХреА рд╕рдореАрдХреНрд╖рд╛ рдХреА рд╣реИ рдФрд░ рдЗрд╕рдХреА рджреАрд░реНрдШрдХрд╛рд▓рд┐рдХ рд╕реНрдерд┐рд░рддрд╛ рдореЗрдВ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдорд╣рд╕реВрд╕ рдХрд░рддреЗ рд╣реИрдВред

рдПрдХреНрд╕реЛрдирдо рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рд▓рд┐рдП, рдПрдХреНрдЯрд┐рдХреНрд╕ рдореЗрдВ рд╢рд┐рдлреНрдЯрд┐рдВрдЧ рдиреЗ рдСрдкрд░реЗрд╢рди рд╕реНрдерд┐рд░рддрд╛ рдХреЗ рдореБрджреНрджреЗ рдХреЛ рд╣рд▓ рдХрд┐рдпрд╛ред рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдХрдиреЗрдХреНрд╢рди рд╣реЛрдиреЗ рдкрд░ рдЖрдпрд░рди рдлреНрд░реЗрдорд╡рд░реНрдХ рд╡рд┐рдлрд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╣рдордиреЗ рдпрд╣ рднреА рдкрд╛рдпрд╛ рд╣реИ рдХрд┐ рдПрдХреНрдЯрд┐рдХреНрд╕-рд╡реЗрдм рдПрдкреАрдЖрдИ рд╕рд░рд▓, рдЕрдзрд┐рдХ рдЙрддреНрдкрд╛рджрдХ рдФрд░ рдЕрдзрд┐рдХ рдПрдХреАрдХреГрдд рд╣реИред рд╣рдореЗрдВ рд╡рд┐рд╢реНрд╡рд╛рд╕ рд╣реИ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдФрд░ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рдкрд╛рд╕ рдПрдХреНрд╕реЛрдирдо рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЖрд╕рд╛рди рд╕рдордп рд╣реЛрдЧрд╛, рдЬреЛ рдЕрдм рдПрдХреНрдЯрд┐рдХреНрд╕-рд╡реЗрдм рдбрд┐рдЬрд╝рд╛рдЗрди рдХреЗ рд▓рд┐рдП рддреЗрдЬреА рд╕реЗ рдзрдиреНрдпрд╡рд╛рдж рд╕рдВрдЪрд╛рд▓рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рд╡реЗрдм рдлреНрд░реЗрдорд╡рд░реНрдХ рд╕реЗ рд╣рдореЗрдВ рдХреНрдпрд╛ рдЪрд╛рд╣рд┐рдП


рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рджреМрд░рд╛рди рд╣рдордиреЗ рдорд╣рд╕реВрд╕ рдХрд┐рдпрд╛ рдХрд┐ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдерд╛ рдХрд┐ рд╣рдо рдХреЗрд╡рд▓ рд░реВрдкрд░реЗрдЦрд╛рдУрдВ рдХреЛ рд╢рд┐рдлреНрдЯ рди рдХрд░реЗрдВ, рдмрд▓реНрдХрд┐ рдХрд┐рд╕реА рднреА рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡реЗрдм рдврд╛рдВрдЪреЗ рд╕реЗ рд╕реНрд╡рддрдВрддреНрд░ рдПрдХ рдирдП рдПрдкреАрдЖрдИ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЛ рднреА рд╡рд┐рдХрд╕рд┐рдд рдХрд░реЗрдВред рдЗрд╕ рддрд░рд╣ рдХреА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рд╡реЗрдм рд╕реНрдкреЗрд╕рд┐рдХреНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреЛрдИ рдЪрд┐рдВрддрд╛ рдирд╣реАрдВ рд╣реИ, рдФрд░ рдЙрдиреНрд╣реЗрдВ рдХрд┐рд╕реА рднреА рдмреИрдХреЗрдВрдб рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИрдВрдбрд▓рд░ рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред рдЗрд╕ рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреЛ рдПрдХ рдлреНрд░рдВрдЯрдПрдВрдб рд▓рд┐рдЦрдХрд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдореВрд▓ рдкреНрд░рдХрд╛рд░ рдФрд░ рд▓рдХреНрд╖рдг рд▓рд╛рдЧреВ рдХрд░реЗрдЧрд╛ред

рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдЗрд╕ рджреГрд╢реНрдп рдХреЛ рджреЗрдЦрдиреЗ рдХреА рдХреНрдпрд╛ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЖрдЗрдП рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ рдХрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреЛрдИ HTTP рдПрдкреАрдЖрдИ рдХреНрдпрд╛ рд╣реИ:

  • рдЕрдиреБрд░реЛрдз рдЧреНрд░рд╛рд╣рдХреЛрдВ рджреНрд╡рд╛рд░рд╛ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ; рд╕рд░реНрд╡рд░ рдХреЗрд╡рд▓ рдЙрдирдХреЗ рдкреНрд░рддрд┐ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд░рддрд╛ рд╣реИ (рд╕рд░реНрд╡рд░ рдЕрдиреБрд░реЛрдз рдЖрд░рдВрдн рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ)ред
  • рдЕрдиреБрд░реЛрдз рдпрд╛ рддреЛ рдбреЗрдЯрд╛ рдкрдврд╝рддреЗ рд╣реИрдВ рдпрд╛ рдбреЗрдЯрд╛ рдмрджрд▓рддреЗ рд╣реИрдВред
  • рдЕрдиреБрд░реЛрдз рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╕рд░реНрд╡рд░ рдПрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╕рдлрд▓рддрд╛ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдбреЗрдЯрд╛ рд╣реЛрддрд╛ рд╣реИ; рдпрд╛ рд╡рд┐рдлрд▓рддрд╛ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рддреНрд░реБрдЯрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реАред

рдпрджрд┐ рд╣рдо рд╕рднреА рдЕрдореВрд░реНрдд рдкрд░рддреЛрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рдХреЛрдИ HTTP рдЕрдиреБрд░реЛрдз рдХреЗрд╡рд▓ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рд╣реИ:

 fn request(context: &ServiceContext, query: Query) -> Result<Response, ServiceError> 

рдмрд╛рдХреА рд╕рдм рдХреБрдЫ рдЗрд╕ рдореВрд▓ рдЗрдХрд╛рдИ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдорд╛рдирд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдПрдХ рд╡реЗрдм рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реЗ рд╕реНрд╡рддрдВрддреНрд░ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдКрдкрд░ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рдорд╛рди рд╢реИрд▓реА рдореЗрдВ рд╣реИрдВрдбрд▓рд░ рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

HTTP- рд░рд┐рдХреНрд╡реЗрд╕реНрдЯ рдХреЗ рдЬреЗрдиреЗрд░рд┐рдХ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП Trait `Endpoint`


рд╕рдмрд╕реЗ рд╕рд░рд▓ рдФрд░ рд╕реАрдзрд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг `рдПрдВрдбрдкреЙрдЗрдВрдЯ 'рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рдШреЛрд╖рд┐рдд рдХрд░реЗрдЧрд╛, рдЬреЛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИ:

 // A trait describing GET request handlers. It should be possible to call each of the handlers from any freed // thread. This requirement imposes certain restrictions on the trait. Parameters and request results are // configured using associated types. trait Endpoint: Sync + Send + 'static { type Request: DeserializeOwned + 'static; type Response: Serialize + 'static; fn handle(&self, context: &Context, request: Self::Request) -> Result<Self::Response, io::Error>; } 

рдЕрдм рд╣рдореЗрдВ рдЗрд╕ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдврд╛рдВрдЪреЗ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХреНрдЯрд┐рдХреНрд╕-рд╡реЗрдм рдореЗрдВ рдпрд╣ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреА рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

 // Response type in actix-web. Note that they are asynchronous, even though `Endpoint` assumes that // processing is synchronous. type FutureResponse = actix_web::FutureResponse<HttpResponse, actix_web::Error>; // A raw request handler for actix-web. This is what the framework ultimately works with. The handler // receives parameters from an arbitrary context, through which the request parameters are passed. type RawHandler = dyn Fn(HttpRequest<Context>) -> FutureResponse + 'static + Send + Sync; // For convenience, let's put everything we need from the handler into a single structure. #[derive(Clone)] struct RequestHandler { /// The name of the resource. pub name: String, /// HTTP method. pub method: actix_web::http::Method, /// The raw handler. Note that it will be used from multiple threads. pub inner: Arc<RawHandler>, } 

рд╣рдо рд╕рдВрджрд░реНрдн рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЕрдиреБрд░реЛрдз рдкреИрд░рд╛рдореАрдЯрд░ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдПрдХреНрдЯрд┐рдХреНрд╕-рд╡реЗрдм рд╕рд░реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдбрд┐рд╕реЗрд░рд▓рд╛рдЗрдЬрд╝ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ = 15 рдФрд░ рдмреА = рд╣реИрд▓реЛ рдЗрд╕ рддрд░рд╣ рдПрдХ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ deserialized рд╣реИ:

 #[derive(Deserialize)] struct SimpleQuery { a: i32, b: String, } 

рдпрд╣ deserialization рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╕рдВрдмрджреНрдз рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдиреБрд░реЛрдз рдХреЗ рд╕рд╛рде `рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ` рд╡рд┐рд╢реЗрд╖рддрд╛ рд╕реЗ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╕рд╣рдордд рд╣реИред

рдЗрд╕рдХреЗ рдмрд╛рдж, рдПрдХ рдПрдбреЗрдкреНрдЯрд░ рдХреЛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рджреЗрддрд╛ рд╣реИ рдЬреЛ рдПрдХреНрдЯрд┐рдХреНрд╕-рд╡реЗрдм рдХреЗ рд▓рд┐рдП рдПрдХ рд░рд┐рдХреНрд╡реЗрдиреНрдбрд░рд▓рд░ рдореЗрдВ `рдПрдВрдбрдкреЙрдЗрдВрдЯ 'рдХреЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рд▓рдкреЗрдЯрддрд╛ рд╣реИред рдЗрд╕ рддрдереНрдп рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдРрд╕рд╛ рдХрд░рддреЗ рд╕рдордп, рдЕрдиреБрд░реЛрдз рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдирдХрд╛рд░реА рдЧрд╛рдпрдм рд╣реЛ рдЬрд╛рддреА рд╣реИред рдЗрд╕ рддрдХрдиреАрдХ рдХреЛ рдЯрд╛рдЗрдк рдЗрд░реЗрдЬрд╝рд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ - рдпрд╣ рд╕реНрдЯреЗрдЯрд┐рдХ рдбрд┐рд╕реНрдкреИрдЪрд┐рдВрдЧ рдХреЛ рдбрд╛рдпрдирд╛рдорд┐рдХ рдореЗрдВ рдмрджрд▓ рджреЗрддреА рд╣реИред

 impl RequestHandler { fn from_endpoint<E: Endpoint>(name: &str, endpoint: E) -> RequestHandler { let index = move |request: HttpRequest<Context>| -> FutureResponse { let context = request.state(); let future = Query::from_request(&request, &()) .map(|query: Query<E::Request>| query.into_inner()) .and_then(|query| endpoint.handle(context, query).map_err(From::from)) .and_then(|value| Ok(HttpResponse::Ok().json(value))) .into_future(); Box::new(future) }; Self { name: name.to_owned(), method: actix_web::http::Method::GET, inner: Arc::from(index) as Arc<RawHandler>, } } } 

рдЗрд╕ рд╕реНрддрд░ рдкрд░, рдпрд╣ рдХреЗрд╡рд▓ POST рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд▓рд┐рдП рд╣реИрдВрдбрд▓рд░ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рд╣рдордиреЗ рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рдмрдирд╛рдИ рд╣реИ рдЬреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рд╡рд░рдг рд╕реЗ рд╕реНрд╡рддрдВрддреНрд░ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╣рдордиреЗ рдкрд╛рдпрд╛ рдХрд┐ рдпрд╣ рд╕рдорд╛рдзрд╛рди рдкрд░реНрдпрд╛рдкреНрдд рд░реВрдк рд╕реЗ рдЙрдиреНрдирдд рдирд╣реАрдВ рдерд╛ред

`рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ` рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреА рдХрдорд┐рдпрд╛рдВ


рдПрдХ рд╣реИрдВрдбрд▓рд░ рд▓рд┐рдЦреЗ рдЬрд╛рдиреЗ рдкрд░ рд╕рд╣рд╛рдпрдХ рдХреЛрдб рдХреА рдПрдХ рдмрдбрд╝реА рдорд╛рддреНрд░рд╛ рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИ:

 // A structure with the context of the handler. struct ElementCountEndpoint { elements: Rc<RefCell<Vec<Something>>>, } // Implementation of the `Endpoint` trait. impl Endpoint for ElementCountEndpoint { type Request = (); type Result = usize; fn handle(&self, context: &Context, _request: ()) -> Result<usize, io::Error> { Ok(self.elements.borrow().len()) } } // Installation of the handler in the backend. let endpoint = ElementCountEndpoint::new(elements.clone()); let handler = RequestHandler::from_endpoint("/v1/element_count", endpoint); actix_backend.endpoint(handler); 

рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ, рд╣рдореЗрдВ рдПрдХ рд╣реИрдВрдбрд▓рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╕рд░рд▓ рдХреНрд▓реЛрдЬрд░ рдкрд╛рд╕ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╕рд┐рдВрдЯреИрдХреНрдЯрд┐рдХ рд╢реЛрд░ рдХреА рдорд╛рддреНрд░рд╛ рдХреЛ рдХрдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

 let elements = elements.clone(); actix_backend.endpoint("/v1/elements_count", move || { Ok(elements.borrow().len()) }); 

рдиреАрдЪреЗ рд╣рдо рдЪрд░реНрдЪрд╛ рдХрд░реЗрдВрдЧреЗ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдЬреЗрдиреЗрд░рд┐рдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдореЗрдВ рд▓рд╛рдЗрдЯ рд╡рд┐рд╕рд░реНрдЬрди


рд╣рдореЗрдВ рдПрдХ рдПрдбрд╛рдкреНрдЯрд░ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рд╕рд╣реА рд╕рдВрдмрджреНрдз рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде `рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ` рдЧреБрдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рдЗрдирдкреБрдЯ рдореЗрдВ рдХреЗрд╡рд▓ HTTP рдЕрдиреБрд░реЛрдз рд╣реИрдВрдбрд▓рд░ рдХреЗ рд╕рд╛рде рдПрдХ рдХреНрд▓реЛрдЬрд░ рд╢рд╛рдорд┐рд▓ рд╣реЛрдЧрд╛ред

рддрд░реНрдХ рдФрд░ рдмрдВрдж рд╣реЛрдиреЗ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдпрд╣рд╛рдВ рдУрд╡рд░рд▓реЛрдбрд┐рдВрдЧ рдХреЗ рддрд░реАрдХреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЬрдВрдЧ рд╕реАрдзреЗ рдУрд╡рд░рд▓реЛрдбрд┐рдВрдЧ рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддреА рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕реЗ `рдЗрдиреНрдЯреЛ` рдФрд░` рдлреНрд░реЙрдо` рд▓рдХреНрд╖рдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХреНрд▓реЛрдЬрд░ рд╡реИрд▓реНрдпреВ рдХрд╛ рд▓реМрдЯрд╛ рд╣реБрдЖ рдкреНрд░рдХрд╛рд░ `рдПрдВрдбрдкреЙрдЗрдВрдЯ` рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓реМрдЯреЗ рдореВрд▓реНрдп рд╕реЗ рдореЗрд▓ рдирд╣реАрдВ рдЦрд╛рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рд╣реЗрд░рдлреЗрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХреНрд▓реЛрдЬрд░ рдХреЗ рдкреНрд░рдХрд╛рд░ рд╕реЗ рдирд┐рдХрд╛рд▓рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

`Fn` рд╡рд┐рд╢реЗрд╖рддрд╛ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдкреНрд░рдХрд╛рд░


рдЬрдВрдЧ рдореЗрдВ, рдкреНрд░рддреНрдпреЗрдХ рдмрдВрдж рдХрд╛ рдЕрдкрдирд╛ рдЕрд▓рдЧ рдкреНрд░рдХрд╛рд░ рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЗрдВрдЧрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдХреНрд▓реЛрдЬрд░ рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝рддреЛрдбрд╝ рдХреЗ рд▓рд┐рдП, рд╣рдо `Fn` рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рд╡рд┐рд╢реЗрд╖рддрд╛ рдореЗрдВ рддрд░реНрдХреЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░ рдФрд░ рд▓реМрдЯрд╛рдП рдЧрдП рдорд╛рди рдХреЗ рд╕рд╛рде рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рд╣реЛрддреЗ рд╣реИрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрди рддрддреНрд╡реЛрдВ рдХреЛ рдЕрд▓рдЧ рд╕реЗ рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЖрд╕рд╛рдиреА рд╕реЗ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред

рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлреЙрд░реНрдо рдХреА рдПрдХ рд╕рд╣рд╛рдпрдХ рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ:

 /// Simplified example of extracting types from an F closure: Fn(A) -> B. struct SimpleExtractor<A, B, F> { // The original function. inner: F, _a: PhantomData<A>, _b: PhantomData<B>, } 

рд╣рдореЗрдВ рдлреИрдВрдЯрдордбрд╛рдЯрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЬрдВрдЧ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рд╕рдВрд░рдЪрдирд╛ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдореЗрдВ рд╕рднреА рд╕рд╛рдорд╛рдиреНрдп рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдХреНрд▓реЛрдЬрд░ рдпрд╛ рдлрдВрдХреНрд╢рди F рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╕реНрд╡рдпрдВ рдПрдХ рдЬреЗрдиреЗрд░рд┐рдХ рдирд╣реАрдВ рд╣реИ (рд╣рд╛рд▓рд╛рдБрдХрд┐ рдпрд╣ рдПрдХ рдЬреЗрдиреЗрд░рд┐рдХ `Fn` рдЯреНрд░реИрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ)ред рдП рдФрд░ рдмреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдЗрд╕рдореЗрдВ рд╕реАрдзреЗ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдпрд╣ рд░рд╕реНрдЯ рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдпрд╣ рдкреНрд░рддрд┐рдмрдВрдз рд╣реИ рдЬреЛ рд╣рдореЗрдВ рдХреНрд▓реЛрдЬрд░ рдХреЗ рд▓рд┐рдП рд╕реАрдзреЗ 'рдПрдВрдбрдкреЙрдЗрдВрдЯ' рд╡рд┐рд╢реЗрд╖рддрд╛ рд▓рд╛рдЧреВ рдХрд░рдХреЗ рдПрдХ рд╕рд░рд▓ рд░рдгрдиреАрддрд┐ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╕реЗ рд░реЛрдХрддрд╛ рд╣реИ:

 impl<A, B, F> Endpoint for F where F: Fn(&Context, A) -> B { type Request = A; type Response = B; fn handle(&self, context: &Context, request: A) -> Result<B, io::Error> { // ... } } 

рдЙрдкрд░реЛрдХреНрдд рдорд╛рдорд▓реЗ рдореЗрдВ, рдХрдВрдкрд╛рдЗрд▓рд░ рдПрдХ рддреНрд░реБрдЯрд┐ рджреЗрддрд╛ рд╣реИ:

 error[E0207]: the type parameter `A` is not constrained by the impl trait, self type, or predicates --> src/main.rs:10:6 | 10 | impl<A, B, F> Endpoint for F where F: Fn(&Context, A) -> B { | ^ unconstrained type parameter 

рд╕рд╣рд╛рдпрдХ рд╕рдВрд░рдЪрдирд╛ SimpleExtractor `From` рдХреЗ рд░реВрдкрд╛рдВрддрд░рдг рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдирд╛ рд╕рдВрднрд╡ рдмрдирд╛рддрд╛ рд╣реИред рдпрд╣ рд░реВрдкрд╛рдВрддрд░рдг рд╣рдореЗрдВ рдХрд┐рд╕реА рднреА рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдмрдЪрд╛рдиреЗ рдФрд░ рдЗрд╕рдХреЗ рддрд░реНрдХреЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рдХрд╛рд▓рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ:

 impl<A, B, F> From<F> for SimpleExtractor<A, B, F> where F: Fn(&Context, A) -> B, A: DeserializeOwned, B: Serialize, { fn from(inner: F) -> Self { SimpleExtractor { inner, _a: PhantomData, _b: PhantomData, } } } 

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддрд╛ рд╣реИ:

 #[derive(Deserialize)] struct Query { a: i32, b: String, }; // Verification of the ordinary structure. fn my_handler(_: &Context, q: Query) -> String { format!("{} has {} apples.", qb, qa) } let fn_extractor = SimpleExtractor::from(my_handler); // Verification of the closure. let c = 15; let my_closure = |_: &Context, q: Query| -> String { format!("{} has {} apples, but Alice has {}", qb, qa, c) }; let closure_extractor = SimpleExtractor::from(my_closure); 

рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдФрд░ рдорд╛рд░реНрдХрд░ рдХреЗ рдкреНрд░рдХрд╛рд░


рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд┐рдП рдЧрдП рддрд░реНрдХ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ `рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ` рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рдмрдЬрд╛рдп рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо SimpleExtractor рд╕реЗ RequestHandler рдореЗрдВ рд░реВрдкрд╛рдВрддрд░рдг рдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдлрд┐рд░ рднреА, рдпрд╣ рдПрдХ рдкреВрд░реНрдг рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рд╣реИред рд╣рдореЗрдВ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕реНрддрд░ рдкрд░ GET рдФрд░ POST рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдВрдЪрд╛рд▓рдХреЛрдВ рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ (рдФрд░ рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдФрд░ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╕рдВрдЪрд╛рд▓рдХреЛрдВ рдХреЗ рдмреАрдЪ)ред рдЗрд╕ рдХрд╛рд░реНрдп рдореЗрдВ, рдорд╛рд░реНрдХрд░ рдкреНрд░рдХрд╛рд░ рд╣рдорд╛рд░реА рд╕рд╣рд╛рдпрддрд╛ рдХреЗ рд▓рд┐рдП рдЖрддреЗ рд╣реИрдВред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрдЗрдП SimpleExtractor рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦреЗрдВ рддрд╛рдХрд┐ рдпрд╣ рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдФрд░ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдХрд░ рд╕рдХреЗред рдЙрд╕реА рд╕рдордп, рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП `From` рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдВрдЧреЗред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЛ рдЬреЗрдиреЗрд░рд┐рдХ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

 /// Generic handler for HTTP-requests. pub struct With<Q, I, R, F> { /// A specific handler function. pub handler: F, /// Structure type containing the parameters of the request. _query_type: PhantomData<Q>, /// Type of the request result. _item_type: PhantomData<I>, /// Type of the value returned by the handler. /// Note that this value can differ from the result of the request. _result_type: PhantomData<R>, } // Implementation of an ordinary synchronous returned value. impl<Q, I, F> From<F> for With<Q, I, Result<I>, F> where F: Fn(&ServiceApiState, Q) -> Result<I>, { fn from(handler: F) -> Self { Self { handler, _query_type: PhantomData, _item_type: PhantomData, _result_type: PhantomData, } } } // Implementation of an asynchronous request handler. impl<Q, I, F> From<F> for With<Q, I, FutureResult<I>, F> where F: Fn(&ServiceApiState, Q) -> FutureResult<I>, { fn from(handler: F) -> Self { Self { handler, _query_type: PhantomData, _item_type: PhantomData, _result_type: PhantomData, } } } 

рдЕрдм рд╣рдореЗрдВ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдЕрдиреБрд░реЛрдзрдХрд░реНрддрд╛ рдХреЛ рдЙрд╕рдХреЗ рдирд╛рдо рдФрд░ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝ рджреЗрдЧрд╛:

 #[derive(Debug)] pub struct NamedWith<Q, I, R, F, K> { /// The name of the handler. pub name: String, /// The handler with the extracted types. pub inner: With<Q, I, R, F>, /// The type of the handler. _kind: PhantomData<K>, } 

рдЕрдЧрд▓рд╛, рд╣рдо рдХрдИ рдЦрд╛рд▓реА рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдорд╛рд░реНрдХрд░ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдХрд░реЗрдВрдЧреЗред рдорд╛рд░реНрдХрд░ рд╣рдореЗрдВ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╡рд░реНрдгрд┐рдд RequestHandler рдореЗрдВ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдХреЛрдб рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдВрдЧреЗред

 /// A handler that does not change the state of the service. In HTTP, GET-requests correspond to this // handler. pub struct Immutable; /// A handler that changes the state of the service. In HTTP, POST, PUT, UPDATE and other similar //requests correspond to this handler, but for the current case POST will suffice. pub struct Mutable; 

рдЕрдм рд╣рдо рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреИрд░рд╛рдореАрдЯрд░ R рдФрд░ K рдХреЗ рд╕рднреА рд╕рдВрдпреЛрдЬрдиреЛрдВ рдХреЗ рд▓рд┐рдП `From` рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рдЪрд╛рд░ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдиреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рд╣реИрдВрдбрд▓рд░ рдХрд╛ рд╡рд╛рдкрд╕реА рдореВрд▓реНрдп рдФрд░ рдЕрдиреБрд░реЛрдз рдХрд╛ рдкреНрд░рдХрд╛рд░)ред

 // Implementation of a synchronous handler of GET requests. impl<Q, I, F> From<NamedWith<Q, I, Result<I>, F, Immutable>> for RequestHandler where F: Fn(&ServiceApiState, Q) -> Result<I> + 'static + Send + Sync + Clone, Q: DeserializeOwned + 'static, I: Serialize + 'static, { fn from(f: NamedWith<Q, I, Result<I>, F, Immutable>) -> Self { let handler = f.inner.handler; let index = move |request: HttpRequest| -> FutureResponse { let context = request.state(); let future = Query::from_request(&request, &()) .map(|query: Query<Q>| query.into_inner()) .and_then(|query| handler(context, query).map_err(From::from)) .and_then(|value| Ok(HttpResponse::Ok().json(value))) .into_future(); Box::new(future) }; Self { name: f.name, method: actix_web::http::Method::GET, inner: Arc::from(index) as Arc<RawHandler>, } } } // Implementation of a synchronous handler of POST requests. impl<Q, I, F> From<NamedWith<Q, I, Result<I>, F, Mutable>> for RequestHandler where F: Fn(&ServiceApiState, Q) -> Result<I> + 'static + Send + Sync + Clone, Q: DeserializeOwned + 'static, I: Serialize + 'static, { fn from(f: NamedWith<Q, I, Result<I>, F, Mutable>) -> Self { let handler = f.inner.handler; let index = move |request: HttpRequest| -> FutureResponse { let handler = handler.clone(); let context = request.state().clone(); request .json() .from_err() .and_then(move |query: Q| { handler(&context, query) .map(|value| HttpResponse::Ok().json(value)) .map_err(From::from) }) .responder() }; Self { name: f.name, method: actix_web::http::Method::POST, inner: Arc::from(index) as Arc<RawHandler>, } } } // Implementation of an asynchronous handler of GET requests. impl<Q, I, F> From<NamedWith<Q, I, FutureResult<I>, F, Immutable>> for RequestHandler where F: Fn(&ServiceApiState, Q) -> FutureResult<I> + 'static + Clone + Send + Sync, Q: DeserializeOwned + 'static, I: Serialize + 'static, { fn from(f: NamedWith<Q, I, FutureResult<I>, F, Immutable>) -> Self { let handler = f.inner.handler; let index = move |request: HttpRequest| -> FutureResponse { let context = request.state().clone(); let handler = handler.clone(); Query::from_request(&request, &()) .map(move |query: Query<Q>| query.into_inner()) .into_future() .and_then(move |query| handler(&context, query).map_err(From::from)) .map(|value| HttpResponse::Ok().json(value)) .responder() }; Self { name: f.name, method: actix_web::http::Method::GET, inner: Arc::from(index) as Arc<RawHandler>, } } } // Implementation of an asynchronous handler of POST requests. impl<Q, I, F> From<NamedWith<Q, I, FutureResult<I>, F, Mutable>> for RequestHandler where F: Fn(&ServiceApiState, Q) -> FutureResult<I> + 'static + Clone + Send + Sync, Q: DeserializeOwned + 'static, I: Serialize + 'static, { fn from(f: NamedWith<Q, I, FutureResult<I>, F, Mutable>) -> Self { let handler = f.inner.handler; let index = move |request: HttpRequest| -> FutureResponse { let handler = handler.clone(); let context = request.state().clone(); request .json() .from_err() .and_then(move |query: Q| { handler(&context, query) .map(|value| HttpResponse::Ok().json(value)) .map_err(From::from) }) .responder() }; Self { name: f.name, method: actix_web::http::Method::POST, inner: Arc::from(index) as Arc<RawHandler>, } } } 

рдмреИрдХрдПрдВрдб рдХреЗ рд▓рд┐рдП рдореБрдЦреМрдЯрд╛


рдЕрдВрддрд┐рдо рдЪрд░рдг рдПрдХ рдореБрдЦреМрдЯрд╛ рддреИрдпрд╛рд░ рдХрд░рдирд╛ рд╣реИ рдЬреЛ рдХреНрд▓реЛрдЬрд░ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░реЗрдЧрд╛ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рдмреИрдХреЗрдВрдб рдореЗрдВ рдЬреЛрдбрд╝ рджреЗрдЧрд╛ред рджрд┐рдП рдЧрдП рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдмреИрдХрдПрдВрдб рд╣реИ - рдПрдХреНрдЯрд┐рдХреНрд╕-рд╡реЗрдмред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдореБрдЦреМрдЯрд╛ рдХреЗ рдкреАрдЫреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдХреНрд╖рдорддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП: рд╕реНрд╡реИрдЧрд░ рд╡рд┐рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХрд╛ рдПрдХ рдЬрдирд░реЗрдЯрд░ред

 pub struct ServiceApiScope { actix_backend: actix::ApiBuilder, } impl ServiceApiScope { /// This method adds an Immutable handler to all backends. pub fn endpoint<Q, I, R, F, E>(&mut self, name: &'static str, endpoint: E) -> &mut Self where // Here we list the typical restrictions which we have encountered earlier: Q: DeserializeOwned + 'static, I: Serialize + 'static, F: Fn(&ServiceApiState, Q) -> R + 'static + Clone, E: Into<With<Q, I, R, F>>, // Note that the list of restrictions includes the conversion from NamedWith into RequestHandler // we have implemented earlier. RequestHandler: From<NamedWith<Q, I, R, F, Immutable>>, { self.actix_backend.endpoint(name, endpoint); self } /// A similar method for Mutable handlers. pub fn endpoint_mut<Q, I, R, F, E>(&mut self, name: &'static str, endpoint: E) -> &mut Self where Q: DeserializeOwned + 'static, I: Serialize + 'static, F: Fn(&ServiceApiState, Q) -> R + 'static + Clone, E: Into<With<Q, I, R, F>>, RequestHandler: From<NamedWith<Q, I, R, F, Mutable>>, { self.actix_backend.endpoint_mut(name, endpoint); self } 

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЕрдиреБрд░реЛрдз рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдкреНрд░рдХрд╛рд░, рдЕрдиреБрд░реЛрдз рдкрд░рд┐рдгрд╛рдо рдХреЗ рдкреНрд░рдХрд╛рд░, рдФрд░ рд╣реИрдВрдбрд▓рд░ рдХреА рд╕рдордХрд╛рд▓рд┐рдХрддрд╛ / рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХрддрд╛ рдЕрдкрдиреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рд╕реЗ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХреА рдЬрд╛рддреА рд╣реИред рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рд╣рдореЗрдВ рдЕрдиреБрд░реЛрдз рдХреЗ рдирд╛рдо рдФрд░ рдкреНрд░рдХрд╛рд░ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреА рдХрдорд┐рдпрд╛рдВ


рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рджреГрд╖реНрдЯрд┐рдХреЛрдг, рдХрд╛рдлреА рдкреНрд░рднрд╛рд╡реА рд╣реЛрдиреЗ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдЗрд╕рдХреА рдХрдорд┐рдпрд╛рдВ рд╣реИрдВред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдПрдВрдбрдкреЙрдЗрдВрдЯ рдФрд░ рдПрдВрдбрдкреЙрдЗрдВрдЯ_рдореВрдЯ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдмреИрдХреЗрдВрдб рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рд╡рд┐рд╢рд┐рд╖реНрдЯрддрд╛рдУрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП ред рдпрд╣ рдкреНрд░рддрд┐рдмрдВрдз рд╣рдореЗрдВ рдЪрд▓рддреЗ-рдлрд┐рд░рддреЗ рдмреИрдХрдПрдВрдб рдХреЛ рдЬреЛрдбрд╝рдиреЗ рд╕реЗ рд░реЛрдХрддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╢рд╛рдпрдж рд╣реА рдХрднреА рдЖрд╡рд╢реНрдпрдХ рд╣реИред

рдПрдХ рдФрд░ рдореБрджреНрджрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдЕрддрд┐рд░рд┐рдХреНрдд рддрд░реНрдХ рдХреЗ рдмрд┐рдирд╛ рдХрд┐рд╕реА рд╣реИрдВрдбрд▓рд░ рдХреА рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ ред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдпрджрд┐ рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рддреЛ рдЗрд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдореМрдЬреВрджрд╛ рдЬреЗрдиреЗрд░рд┐рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╡рд┐рд░реЛрдз рдореЗрдВ рд╣реИ:

 impl<(), I, F> From<F> for With<(), I, Result<I>, F> where F: Fn(&ServiceApiState) -> Result<I>, { fn from(handler: F) -> Self { Self { handler, _query_type: PhantomData, _item_type: PhantomData, _result_type: PhantomData, } } } 

рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдЬрд┐рди рдЕрдиреБрд░реЛрдзреЛрдВ рдХрд╛ рдХреЛрдИ рдкреИрд░рд╛рдореАрдЯрд░ рдирд╣реАрдВ рд╣реИ, рдЙрдиреНрд╣реЗрдВ рдЕрднреА рднреА JSON рд╕реНрдЯреНрд░рд┐рдВрдЧ рдирд▓ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреЛ рдХрд┐ () рдореЗрдВ рдбрд┐рд╕реЗрд░реНрд▓рд╛рдЗрдЬрд╝реНрдб рд╣реИред рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ C ++ рд╢реИрд▓реА рдореЗрдВ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рджреНрд╡рд╛рд░рд╛ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдм рдпрд╣ рдХреЗрд╡рд▓ рд╕рдВрдХрд▓рдХ рдХреЗ рд░рд╛рдд рдХреЗ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╣реИ рдФрд░ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рд╕реНрдерд┐рд░ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрдм рдмрдиреЗрдЧреАред

рдЗрд╕реА рдкреНрд░рдХрд╛рд░, рд▓реМрдЯрд╛рдП рдЧрдП рдорд╛рди рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ ред рднрд▓реЗ рд╣реА рдЕрдиреБрд░реЛрдз рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдкреНрд░рдХрд╛рд░ рдХрд╛ рд▓реМрдЯрд╛рдпрд╛ рдЧрдпрд╛ рдорд╛рди рди рд╣реЛ, рдлрд┐рд░ рднреА рдпрд╣ JSON рдХреЛ рдЕрд╢рдХреНрдд рдХрд░ рджреЗрдЧрд╛ред

рдЬреАрдИрдЯреА рдЕрдиреБрд░реЛрдзреЛрдВ рдореЗрдВ рдпреВрдЖрд░рдПрд▓ рдХреНрд╡реЗрд░реА рдХреЛ рдбрд┐рдХреЛрдб рдХрд░рдирд╛ рднреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░ рдкрд░ рдХреБрдЫ рдЕрд╕реНрдкрд╖реНрдЯ рдкреНрд░рддрд┐рдмрдВрдз рд▓рдЧрд╛рддрд╛ рд╣реИ , рд▓реЗрдХрд┐рди рдпрд╣ рдореБрджреНрджрд╛ рд╕рд░реНрдб-рдпреВрд░реЗрд▓реЗрдВрдХреЗрдб рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рд╡рд┐рд╢рд┐рд╖реНрдЯрддрд╛рдУрдВ рдХреЗ рдмрдЬрд╛рдп рд╕рдВрдмрдВрдзрд┐рдд рд╣реИред

рдирд┐рд╖реНрдХрд░реНрд╖


рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рд╣реИ, рд╣рдордиреЗ рдПрдХ рдмреЗрд╣рддрд░ рдПрдкреАрдЖрдИ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рд╣реИ, рдЬреЛ рд╡реЗрдм рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рдмрд┐рдирд╛, рд╣реИрдВрдбрд▓рд░реНрд╕ рдХреА рдПрдХ рд╕рд░рд▓ рдФрд░ рд╕реНрдкрд╖реНрдЯ рд░рдЪрдирд╛ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдпреЗ рд╣реИрдВрдбрд▓рд░ рдХрд┐рд╕реА рднреА рдмреИрдХрдПрдВрдб рдХреЗ рд╕рд╛рде рдпрд╛ рдХрдИ рдмреИрдХрдПрдВрдб рдХреЗ рд╕рд╛рде рднреА рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред





Source: https://habr.com/ru/post/hi439258/


All Articles