[Rust] impl TryFrom and try_into()
The TryFrom
and try_into()
methods are part of the. standard libaray's conversion traits, designed to handle conversions between types in a fallible manner - that is, conversions that might fail.
This is in contrast to `From` and `into()` methods, which are used for infallible conversions, where the conversion is guaranteed to succeed.
Using `TryFrom`
and `try_into()`
provides several benefits and use cases over other approaches:
use anyhow::{Result, anyhow, Context};
use std::path::PathBuf;
use crate::opts::Opts;
#[derive(Debug)]
pub struct Config {
pub operation: Operation,
pub pwd: PathBuf,
pub config: PathBuf,
}
impl TryFrom<Opts> for Config {
type Error = anyhow::Error;
fn try_from(value: Opts) -> Result<Self> {
// when you impl TryFrom, you can use try_into
let operation = value.args.try_into()?;
let config = get_config(value.config)?;
let pwd = get_pwd(value.pwd)?;
return Ok(Config {
operation,
config,
pwd,
});
}
}
#[derive(Debug)]
pub enum Operation {
Print(Option<String>),
Add(String, String),
Remove(String),
}
impl TryFrom<Vec<String>> for Operation {
type Error = anyhow::Error;
fn try_from(value: Vec<String>) -> Result<Self> {
let mut value = value;
if value.len() == 0 {
return Ok(Operation::Print(None));
}
let term = value.get(0).expect("expect to exist");
if term == "add" {
if value.len() != 3 {
return Err(anyhow!("opearation add expected 2 arguements but got {}", value.len() - 1));
}
let mut drain = value.drain(1..=2);
return Ok(
Operation::Add(drain.next().expect("to exist"), drain.next().expect("to exist"))
)
}
if term == "Remove" {
if value.len() != 2 {
return Err(anyhow!("opearation remove expected 1 arguements but got {}", value.len() - 1));
}
let arg = value.pop().expect("to exist");
return Ok(
Operation::Remove(arg)
);
}
if value.len() > 1 {
return Err(anyhow!("operation pritn expects 0 or 1 arguments, but got {}", value.len()));
}
let arg = value.pop().expect("to exist");
return Ok(Operation::Print(Some(arg)));
}
}
fn get_config(config: Option<PathBuf>) -> Result<PathBuf> {
if let Some(v) = config {
return Ok(v);
}
let loc = std::env::var("XDG_CONFIG_HOME").context("unable to get XDG_CONFIG_HOME")?;
let mut loc = PathBuf::from(loc);
loc.push("projector");
loc.push("projector.json");
return Ok(loc);
}
fn get_pwd(pwd: Option<PathBuf>) -> Result<PathBuf> {
if let Some(pwd) = pwd {
return Ok(pwd);
}
return Ok(std::env::current_dir().context("errored getting current_dir")?)
}
分类:
Rust
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2020-02-26 [TypeScript] as const, force immutability for Object type
2020-02-26 [Typescript] Using 'Pick' to create a sub-type from original type
2019-02-26 [Functional Programming] Capture Side Effects in a Task / Async
2019-02-26 [Compose] 9. Delay Evaluation with LazyBox
2019-02-26 [Functional Programming] Unbox types with foldMap
2018-02-26 [HTML5] Inlining images with SVG and data URIs
2016-02-26 [Unit Testing] Directive testing, require parent controller