Skip to content

Commit

Permalink
initial-release
Browse files Browse the repository at this point in the history
  • Loading branch information
inoas committed Dec 14, 2024
0 parents commit b21c75a
Show file tree
Hide file tree
Showing 11 changed files with 865 additions and 0 deletions.
23 changes: 23 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: test

on:
push:
branches:
- master
- main
pull_request:

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1
with:
otp-version: "27.1.2"
gleam-version: "1.6.3"
rebar3-version: "3"
# elixir-version: "1.15.4"
- run: gleam deps download
- run: gleam test
- run: gleam format --check src test
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.beam
*.ez
/build
erl_crash.dump
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Changelog

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

<!-- ## [Unreleased] -->

## [1.0.0] - 2024-12-14

- Initial release.
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @inoas
373 changes: 373 additions & 0 deletions LICENCE

Large diffs are not rendered by default.

164 changes: 164 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# Given for Gleam

[![Package <a href="https://github.com/inoas/gleam-given/releases"><img src="https://img.shields.io/github/release/inoas/gleam-given" alt="GitHub release"></a> Version](https://img.shields.io/hexpm/v/given)](https://hex.pm/packages/given)
[![Erlang-compatible](https://img.shields.io/badge/target-erlang-b83998)](https://www.erlang.org/)
[![JavaScript Compatible](https://img.shields.io/badge/target-javascript-f3e155)](https://en.wikipedia.org/wiki/JavaScript)
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/given/)
[![Discord](https://img.shields.io/discord/768594524158427167?label=discord%20chat&amp;color=5865F2)](https://discord.gg/Fm8Pwmy)
[![CI Test](https://github.com/inoas/gleam-given/actions/workflows/test.yml/badge.svg?branch=main&amp;event=push)](https://github.com/inoas/gleam-given/actions/workflows/test.yml)

<br>
<br>

<p align="center">
<img src="https://raw.githubusercontent.com/inoas/gleam-given/main/given-logo.png" alt="Given Logo" style="max-height: 33vh; width: auto; height: auto" width="480" height="480"/>
</p>

<br>

<p align="center">
<i>
👇Given is a library written in Gleam to make it safe and easy to early return.
</i>
</p>

<br>
<br>

```sh
gleam add given@1
```

```gleam
import given.{given, not_given, given_ok_in, given_error_in, given_some_in, given_none_in}
import gleam/io
pub fn main() {
given_examples()
not_given_examples()
given_ok_in_examples()
given_error_in_examples()
given_some_in_examples()
given_none_in_examples()
}
pub fn given_examples() {
{
let user_understood = False
use <- given(user_understood, return: fn() { great })
// …else user handles case where user did not understand here…
woof
}
|> io.debug()
{
let user_understood = True
use <- given(user_understood, return: fn() { great })
// …else user handles case where user did not understand here…
woof
}
|> io.debug()
}
pub fn not_given_examples() {
{
let user_understood = False
use <- not_given(user_understood, return: fn() { great })
// …else user handles case where user understood here…
woof
}
|> io.debug()
{
let user_understood = True
use <- not_given(user_understood, return: fn() { great })
// …else user handles case where user understood here…
woof
}
|> io.debug()
}
pub fn given_ok_in_examples() {
{
let result = Ok(great)
use ok_value <- given_ok_in(result, else_return: fn(error_value) {
error_value
})
// …user handles Ok value here…
ok_value
}
|> io.debug()
{
let result = Error(woof)
use ok_value <- given_ok_in(result, else_return: fn(error_value) {
error_value
})
// …user handles Ok value here…
ok_value
}
|> io.debug()
}
pub fn given_error_in_examples() {
{
let result = Error(woof)
use error_value <- given_error_in(result, else_return: fn(ok_value) {
ok_value
})
// …user handles Error value here…
error_value
}
|> io.debug()
{
let result = Ok(great)
use error_value <- given_error_in(result, else_return: fn(ok_value) {
ok_value
})
// …user handles Error value here…
error_value
}
|> io.debug()
}
pub fn given_some_in_examples() {
{
let option = Some(great)
use some_value <- given_some_in(option, else_return: fn() { woof })
// …user handles Some value here…
some_value
}
{
let option = Some(great)
use some_value <- given_some_in(option, else_return: fn() { woof })
// …user handles Some value here…
some_value
}
}
pub fn given_none_in_examples() {
{
let option = Some(great)
use <- given_none_in(option, else_return: fn(some_value) { some_value })
// …user handles None here…
woof
}
{
let option = None
use <- given_none_in(option, else_return: fn(some_value) { some_value })
// …user handles None here…
woof
}
}
```

Further documentation can be found at <https://hexdocs.pm/given>.

## Development

```sh
gleam run # Run the project
gleam test # Run the tests
```
Binary file added given.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions gleam.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name = "given"
version = "1.0.0"

# Fill out these fields if you intend to generate HTML documentation or publish
# your project to the Hex package manager.
#
description = "Ergonomic early returns (lazy guards) for Bool, Result and Option types in Gleam"
licences = ["Apache-2.0"]
# repository = { type = "github", user = "", repo = "" }
# links = [{ title = "Website", href = "" }]
#
# For a full reference of all the available options, you can have a look at
# https://gleam.run/writing-gleam/gleam-toml/.

[dependencies]
gleam_stdlib = ">= 0.44.0 and < 2.0.0"

[dev-dependencies]
gleeunit = ">= 1.0.0 and < 2.0.0"
11 changes: 11 additions & 0 deletions manifest.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# This file was generated by Gleam
# You typically do not need to edit this file

packages = [
{ name = "gleam_stdlib", version = "0.47.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "3B22D46743C46498C8355365243327AC731ECD3959216344FA9CF9AD348620AC" },
{ name = "gleeunit", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "F7A7228925D3EE7D0813C922E062BFD6D7E9310F0BEE585D3A42F3307E3CFD13" },
]

[requirements]
gleam_stdlib = { version = ">= 0.44.0 and < 2.0.0" }
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
135 changes: 135 additions & 0 deletions src/given.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
//// This library attempts to make guards:
////
//// - Applicable to `Bool`, `Result` and Option` types.
//// - Ergonomic to use by providing ways to handle both branches early.
//// - Expressive by making it easy to read through function names and labels.
//// - Comprehendable by not having to negate the conditions.
//// - Safe to use by not accidentally running discarded branches much like
//// `bool.lazy_guard`.
////

import gleam/option.{type Option, None, Some}

/// ## Examples
///
/// ```gleam
/// let user_understood = case int.random(1) {
/// 1 -> True
/// _ -> False
/// }
///
/// use <- given(user_understood, return: fn() { "Great!" })
/// // …else handle case where user did not understand here…
/// "Woof!"
/// ```
///
pub fn given(
requirement: Bool,
return consequence: fn() -> a,
otherwise alternative: fn() -> a,
) -> a {
case requirement {
True -> consequence()
False -> alternative()
}
}

/// ## Examples
///
/// ```gleam
/// let user_understood = case int.random(1) {
/// 1 -> True
/// _ -> False
/// }
///
/// use <- not_given(user_understood, return: fn() { "Woof!" })
/// // …else handle case where user understood here…
/// "Great!"
/// ```
///
pub fn not_given(
requirement: Bool,
return consequence: fn() -> a,
otherwise alternative: fn() -> a,
) -> a {
case !requirement {
True -> consequence()
False -> alternative()
}
}

/// ## Examples
///
/// ```gleam
/// use ok_value <- given_ok_in(result, else_return: fn(error_value) { "Error" })
/// // …handle Ok value here…
/// "Ok"
/// ```
///
pub fn given_ok_in(
result result: Result(a, e),
else_return alternative: fn(a) -> c,
otherwise consequence: fn(e) -> c,
) -> c {
case result {
Ok(value) -> alternative(value)
Error(error) -> consequence(error)
}
}

/// ## Examples
///
/// ```gleam
/// use error_value <- given_error_in(result, else_return: fn(ok_value) { "Ok" })
/// // …handle Error value here…
/// "Error"
/// ```
///
pub fn given_error_in(
result result: Result(a, e),
else_return consequence: fn(a) -> c,
otherwise alternative: fn(e) -> c,
) -> c {
case result {
Ok(value) -> consequence(value)
Error(error) -> alternative(error)
}
}

/// ## Examples
///
/// ```gleam
/// use some_value <- given_some_in(option, else_return: fn() { "None" })
/// // …handle Some value here…
/// "Some value"
/// ```
///
pub fn given_some_in(
option option: Option(a),
else_return consequence: fn() -> c,
otherwise alternative: fn(a) -> c,
) -> c {
case option {
Some(value) -> alternative(value)
None -> consequence()
}
}

/// ## Examples
///
/// ```gleam
/// use none_value <- given_none_in(option, else_return: fn(some_value) { "Some value" })
/// // …handle None value here…
/// "None"
/// ```
///
pub fn given_none_in(
option option: Option(a),
else_return consequence: fn(a) -> c,
otherwise alternative: fn() -> c,
) -> c {
case option {
Some(value) -> consequence(value)
None -> alternative()
}
}
Loading

0 comments on commit b21c75a

Please sign in to comment.