result-like-0.4.6/.cargo_vcs_info.json0000644000000001360000000000100133030ustar { "git": { "sha1": "c365bec85765aac07ddda1cf080d1bfb4659d2fd" }, "path_in_vcs": "" }result-like-0.4.6/.github/workflows/ci.yml000064400000000000000000000015451046102023000166130ustar 00000000000000name: Rust on: push: branches: [ main ] pull_request: branches: env: CARGO_TERM_COLOR: always jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: stable components: rustfmt override: true - name: rustfmt uses: actions-rs/cargo@v1 with: command: fmt args: --all -- --check - name: run check uses: actions-rs/cargo@v1 with: command: check args: ${{ matrix.default }} --verbose - name: run test uses: actions-rs/cargo@v1 with: command: test args: ${{ matrix.default }} --verbose - name: clippy uses: actions-rs/cargo@v1 with: command: clippy args: ${{ matrix.default }} -- -Dwarnings result-like-0.4.6/.gitignore000064400000000000000000000001101046102023000140530ustar 00000000000000 target/ Cargo.lock .vscode/* !.vscode/settings.json /.idea .DS_Storeresult-like-0.4.6/Cargo.toml0000644000000020250000000000100113000ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" name = "result-like" version = "0.4.6" authors = ["Jeong YunWon "] description = "Option/Result-like monad interface for your own enum" homepage = "https://github.com/youknowone/result-like" documentation = "http://docs.rs/result-like" readme = "README.md" keywords = [ "option", "result", "monad", "macro", "enum", ] license = "BSD-2-Clause" repository = "https://github.com/youknowone/result-like" [dependencies.result-like-derive] version = "0.4.6" [dev-dependencies.is-macro] version = "0.1" result-like-0.4.6/Cargo.toml.orig000064400000000000000000000012531046102023000147630ustar 00000000000000[package] name = "result-like" description = "Option/Result-like monad interface for your own enum" version = "0.4.6" homepage = "https://github.com/youknowone/result-like" documentation = "http://docs.rs/result-like" repository = "https://github.com/youknowone/result-like" authors = ["Jeong YunWon "] edition = "2021" license = "BSD-2-Clause" keywords = ["option", "result", "monad", "macro", "enum"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [workspace] members = ["derive/"] [dependencies] result-like-derive = { version = "0.4.6", path = "derive/" } [dev-dependencies] is-macro = "0.1" result-like-0.4.6/LICENSE000064400000000000000000000030151046102023000130770ustar 00000000000000Copyright (c) 2020, Jeong YunWon All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project.result-like-0.4.6/README.md000064400000000000000000000020371046102023000133540ustar 00000000000000# OptionLike and ResultLike Install: [https://crates.io/crates/result-like](https://crates.io/crates/result-like) Define your own Option-like and Result-like enum types. Avoid to reimplement everything of option and result for your own enums. Option example ```rust use result_like::OptionLike; // Simple case with single argument name to use Some and None #[derive(OptionLike)] enum MyOption { Some(T), None, } let v = MyOption::Some(1); // every option utilities are possible including unwrap, map, and, or etc. assert_eq!(v.unwrap(), 1); // convertable to option let opt = v.into_option(); assert_eq!(opt, Some(1)); // enum with custom names instead of Some and None #[derive(OptionLike)] enum Number { Value(i64), Nan, } let v = Number::Value(10); assert_ne!(v, Number::Nan); ``` Result example in same way ```rust use result_like::ResultLike; // typical #[derive(ResultLike)] enum MyResult { Ok(T), Err(E), } // value-only #[derive(ResultLike)] enum Trial { Success(String), Failure(String), } ``` result-like-0.4.6/src/lib.rs000064400000000000000000000111311046102023000137730ustar 00000000000000//! # OptionLike and ResultLike //! //! Define your own Option-like and Result-like enum types. //! Avoid to reimplement everything of [std::option::Option] and [std::result::Result] for your own enums. //! //! Option example //! ```rust //! use result_like::OptionLike; //! //! // Simple case with single argument name to use Some and None //! #[derive(OptionLike, Clone, Copy)] //! enum MyOption { //! Some(u32), //! None //! } //! //! let v = MyOption::Some(1); //! // every option utilities are possible including unwrap, map, and, or etc. //! assert_eq!(v.unwrap(), 1); //! //! // convertable to option //! let opt = v.into_option(); //! assert_eq!(opt, Some(1)); //! ``` //! //! Result example in same way //! ```rust //! use result_like::ResultLike; //! //! #[derive(ResultLike)] //! enum Trial { //! Success(T), //! Failure(E), //! } //! ``` //! //! # BoolLike //! //! BoolLike is comparably simpler than OptionLike and ResultLike. //! //! ```rust //! use result_like::BoolLike; //! //! #[derive(BoolLike, Clone, Copy, Debug, PartialEq, Eq)] //! enum MyBool { //! Enabled, //! Disabled, //! } //! //! let v = MyBool::Enabled; //! assert!(v.to_bool()); //! assert!(!MyBool::Disabled.to_bool()); //! assert_eq!(MyBool::from_bool(true), MyBool::Enabled); //! assert_eq!(v.then(|| 1), Some(1)); //! assert_eq!(v.then_some(1), Some(1)); //! //! #[derive(BoolLike)] //! enum ValuedBool { //! Something = 50, //! Nothing = 10, //! } //! assert!(ValuedBool::Something.to_bool()); //! assert!(ValuedBool::Something as u8 == 50); //! ``` extern crate result_like_derive; pub use result_like_derive::*; pub trait BoolLike where Self: Sized, { } pub trait OptionLike where Self: Sized, { type SomeType; // fn from_value(value: Self::SomeType) -> Self; // fn from_option(option: Option) -> Self; // fn into_option(self) -> Option; // fn as_option(&self) -> Option<&Self::SomeType>; // fn as_option_mut(&mut self) -> Option<&mut Self::SomeType>; // fn get_or_insert_with<_Function: FnOnce() -> Self::SomeType>( // &mut self, // f: _Function, // ) -> &mut Self::SomeType; // #[inline] // fn expect(self, msg: &str) -> Self::SomeType where { // self.into_option().expect(msg) // } // #[inline] // fn unwrap(self) -> Self::SomeType { // self.into_option().unwrap() // } // #[inline] // fn unwrap_or(self, default: Self::SomeType) -> Self::SomeType { // self.into_option().unwrap_or(default) // } // #[inline] // fn unwrap_or_else<_Function: FnOnce() -> Self::SomeType>(self, f: _Function) -> Self::SomeType { // self.into_option().unwrap_or_else(f) // } // #[inline] // fn ok_or<_Error>(self, err: _Error) -> Result { // self.into_option().ok_or(err) // } // #[inline] // fn ok_or_else<_Error, _Function: FnOnce() -> _Error>( // self, // err: _Function, // ) -> Result { // self.into_option().ok_or_else(err) // } // #[inline] // fn filter bool>(self, predicate: P) -> Self { // Self::from_option(self.into_option().filter(predicate)) // } // #[inline] // fn or(self, optb: Self) -> Self { // Self::from_option(self.into_option().or(optb.into_option())) // } // #[inline] // fn or_else<_Function: FnOnce() -> Self>(self, f: _Function) -> Self { // Self::from_option(self.into_option().or_else(|| f().into_option())) // } // #[inline] // fn map_or<_Other, _Function: FnOnce(Self::SomeType) -> _Other>( // self, // default: _Other, // f: _Function, // ) -> _Other { // self.into_option().map_or(default, f) // } // #[inline] // fn xor(self, optb: Self) -> Self { // Self::from_option(self.into_option().xor(optb.into_option())) // } // #[inline] // fn get_or_insert(&mut self, v: Self::SomeType) -> &mut Self::SomeType { // self.get_or_insert_with(|| v) // } // #[inline] // fn take(&mut self) -> Self // where // Self: Default, // { // std::mem::take(self) // } // #[inline] // fn replace(&mut self, value: Self::SomeType) -> Self { // std::mem::replace(self, Self::from_value(value)) // } // #[inline] // fn unwrap_or_default(self) -> Self::SomeType // where // Self::SomeType: Default, // { // self.into_option().unwrap_or_default() // } } pub trait ResultLike { type OkType; type ErrType; } result-like-0.4.6/tests/option.rs000064400000000000000000000017431046102023000151200ustar 00000000000000use result_like::OptionLike; #[test] fn test_generation() { #[derive(OptionLike)] enum ValueOption { Some(i32), None, } assert_eq!(ValueOption::Some(10).into_option(), Some(10)); #[derive(OptionLike)] enum GenericOption { Some(U), None, } assert_eq!(GenericOption::Some("x").into_option(), Some("x")); struct X; #[derive(OptionLike)] enum BareOption { Some(X), None, } } #[test] fn test_xo() { #[derive(OptionLike)] enum XOption { Some(T), None, } let xo = XOption::Some(1); assert!(xo.unwrap() == 1); let op = xo.into_option(); assert!(op == Some(1)); } #[test] fn test_yo() { #[derive(OptionLike, is_macro::Is)] enum YOption { Tone(T), Mome, } let xo = YOption::Tone("s"); assert!(xo.is_tone()); assert!(xo.unwrap() == "s"); let op = xo.into_option(); assert!(op == Some("s")); } result-like-0.4.6/tests/result.rs000064400000000000000000000024531046102023000151250ustar 00000000000000use result_like::ResultLike; #[test] fn test_x() { #[derive(Clone)] struct A; } #[test] fn test_simple() { #[derive(ResultLike, Clone, Copy)] enum XResult { Ok(u32), Err(()), } let xo = XResult::Ok(1); assert_eq!(xo.unwrap(), 1); let op = xo.into_result(); assert_eq!(op, Ok(1)); let xo = xo.map_or(0, |v| v * 2); assert_eq!(xo, 2); assert_eq!(XResult::Err(()).as_result(), Err(&())); } #[allow(dead_code)] #[test] fn test_gen() { #[derive(ResultLike)] enum ResultA { Ok(T), Err(()), } assert_eq!(ResultA::Ok(10).map(|i| i * 2).unwrap(), 20); #[derive(ResultLike)] enum ResultB { Ok(i32), Err(E), } assert_eq!(ResultB::Err(10).or::<()>(ResultB::Ok(10)).unwrap(), 10); #[derive(Debug)] struct Elem; #[derive(ResultLike)] enum ResultC { Ok(Elem), // test no-copy Err(E), } } #[test] fn test_result() { #[derive(ResultLike)] enum YResult { Okay(T), Errr(E), } let mut xo: YResult<&str, ()> = YResult::Okay("s"); assert_eq!(xo.unwrap(), "s"); let op = xo.into_result(); assert_eq!(op, Ok("s")); xo = xo.and_then(|_| YResult::Errr(())); assert_eq!(xo.into_result(), Err(())); }