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}