gan/lib.rs
1/*!
2# Gan - 干就完了!
3
4`干!` 核心原则是帮开发者更果决地处理返回值。提供了忽略结果/快速构造默认值的快捷方式。
5"Just do it!" philosophy. Provides ergonomic value handling with ignore/ok/some semantics.
6## Quick Start
7
8Add to your `Cargo.toml` :
9```toml
10[dependencies]
11gan = "0.1"
12```
13
14## Usage Examples
15
16| Operation | Expression Example | Return Type | Example Use Case |
17|--------------------------|------------------------|-----------------|------------------------------------------|
18| **Ignore Result** | `expr.ignore()` | `()` | `format!("{}", 42).ignore();` |
19| **Construct Ok Unit** | `expr.ok()` | `Result<(), E>` | `write!(file, "{}", data)?.ok()` |
20| **Construct Ok Unit** | `result.ignore().ok()` | `Result<(), E>` | `write!(file, "{}", data).ignore().ok()` |
21| **Construct Ok Wrapped** | `expr.okay()` | `Result<T, E>` | `42.okay()` |
22| **Construct Some Value** | `expr.some()` | `Option<T>` | `42.some()` |
23| **Construct None Value** | `expr.none()` | `Option<U>` | `42.none()` |
24*/
25#![doc(html_root_url = "https://docs.rs/gan/latest")]
26
27/// 核心拓展方法集
28/// Core extension trait
29pub trait Gan: Sized {
30 /// 直接忽略当前值
31 /// Ignores the value completely (alternative to `let _ = ...`)
32 ///
33 /// # 示例 / Example
34 /// ```rust
35 /// //使用前 / Before:
36 /// let _ = format!("{}", 42);
37 /// //使用后 / After:
38 /// use gan::Gan;
39 /// format!("{}", 42).ignore();
40 /// ```
41 #[inline(always)]
42 fn ignore(self) {}
43
44 /// 消耗当前值并返回 Ok
45 /// Consumes the value and returns Ok
46 /// 故意命名为ok,由于 Result 的 ok 方法已经被占用,所以避免被误用,Result 必须通过 .ignore().ok()来显式忽略并返回ok
47 /// Named as ok to avoid conflict with Result's ok method. Result must be explicitly ignored and returned as ok using .ignore().ok()
48 ///
49 /// # 示例 / Example
50 /// ```rust
51 /// //使用前 / Before:
52 /// use std::io::{Write,Error};
53 /// use std::fs::OpenOptions;
54 /// fn write_(file: &str, data:&str) -> Result<(), Error> {
55 /// let mut file = OpenOptions::new().append(true).open(file)?;
56 /// write!(file, "{}", data)?;
57 /// Ok(())
58 /// }
59 /// //使用后 / After:
60 /// use gan::Gan;
61 /// fn write(file: &str, data:&str) -> Result<(), Error> {
62 /// let mut file = OpenOptions::new().append(true).open(file)?;
63 /// write!(file, "{}", data)?.ok()
64 /// // write!(file, "{}", data).ok()// 无法通过编译,防止错误的省略?
65 /// }
66 /// ```
67 #[inline(always)]
68 fn ok<E>(self) -> Result<(), E> {
69 Ok(())
70 }
71
72 /// 返回原值的 Ok 包装
73 /// Wraps self into Ok variant
74 ///
75 /// # 示例 / Example
76 /// ```rust
77 /// //使用前 / Before:
78 /// fn get_data_() -> Result<i32, String> {
79 /// Ok(42)
80 /// }
81 /// //使用后 / After:
82 /// use gan::Gan;
83 /// fn get_data() -> Result<i32, String> {
84 /// 42.okay()
85 /// }
86 #[inline(always)]
87 fn okay<E>(self) -> Result<Self, E> {
88 Ok(self)
89 }
90
91 /// 返回 Some 包装
92 /// Wraps into Some
93 ///
94 /// # 示例 / Example
95 /// ```rust
96 /// //使用前 / Before:
97 /// let opt: Option<i32> = Some(42);
98 /// //使用后 / After:
99 /// use gan::Gan;
100 /// let opt: Option<i32> = 42.some();
101 /// ```
102 #[inline(always)]
103 fn some(self) -> Option<Self> {
104 Some(self)
105 }
106
107 /// 构造空 None 值
108 /// Creates None of a type while ignoring self
109 ///
110 /// # 示例 / Example
111 /// ```rust
112 /// //使用前 / Before:
113 /// let opt: Option<i32> = None;
114 /// //使用后 / After:
115 /// use gan::Gan;
116 /// let opt: Option<i32> = 42.none();
117 /// ```
118 #[inline(always)]
119 fn none<E>(self) -> Option<E> {
120 None
121 }
122}
123
124// 为所有类型实现 Gan
125impl<T: Sized> Gan for T {}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130 use std::io::Write;
131
132 #[test]
133 fn test_basic_operations() {
134 // Test ignore
135 let _ = 42.ignore();
136
137 // Test ok
138 assert_eq!("error".ok::<String>(), Ok(()));
139
140 // Test okay
141 assert_eq!(42.okay::<String>(), Ok(42));
142
143 // Test some
144 assert_eq!(42.some(), Some(42));
145
146 // Test none
147 let opt: Option<i32> = 42.none();
148 assert!(opt.is_none());
149 }
150
151 #[test]
152 fn type_inference_samples() {
153 // 类型推断测试
154 let _: Option<String> = "test".none();
155 let _: Result<i32, String> = 123.okay();
156 }
157
158 #[test]
159 fn result_usage()-> Result<(), String> {
160 // Result 使用测试
161 fn get_result() -> Result<(), String> {
162 match "42".parse::<i32>() {
163 Ok(_) => write!(std::io::stdout(), "Parsed successfully\n").ignore().ok(),
164 // Ok(_) => write!(std::io::stdout(), "Parsed successfully\n").ok(),//应该无法通过编译
165 Err(_) => Err("Failed to parse".to_string()),
166 }
167 }
168 get_result()
169 }
170
171 #[test]
172 fn chaining_usage() {
173 // 链式调用测试
174 let res = "42"
175 .parse::<i32>()
176 .and_then(|n| n.checked_add(1).unwrap().okay());
177
178 assert_eq!(res, Ok(43));
179 }
180}