-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
249 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# This file was generated by Gleam | ||
# You typically do not need to edit this file | ||
|
||
packages = [ | ||
{ name = "ansi", version = "0.1.0", build_tools = ["rebar3"], requirements = [], otp_app = "ansi", source = "hex", outer_checksum = "4BF92B41E29E0480350A3260DC3F7ED52073C56FE236EFCAB1680A5E4C3923A5" }, | ||
{ name = "gleam_stdlib", version = "0.38.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "663CF11861179AF415A625307447775C09404E752FF99A24E2057C835319F1BE" }, | ||
{ name = "gleeunit", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "72CDC3D3F719478F26C4E2C5FED3E657AC81EC14A47D2D2DEBB8693CA3220C3B" }, | ||
] | ||
|
||
[requirements] | ||
ansi = { version = ">= 0.1.0 and < 1.0.0"} | ||
gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" } | ||
gleeunit = { version = ">= 1.0.0 and < 2.0.0" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,26 @@ | ||
import gleam/io | ||
import glitzer/progress | ||
|
||
@external(erlang, "glitzer_ffi", "sleep") | ||
@external(javascript, "./glitzer_ffi.mjs", "sleep") | ||
pub fn sleep(ms: Int) -> a | ||
|
||
pub fn main() { | ||
io.println("Hello from glitzer!") | ||
let bar = progress.default_bar() | ||
|
||
do_something(bar, 0) | ||
} | ||
|
||
fn do_something(bar, count) { | ||
case count < 100 { | ||
True -> { | ||
let bar = case count > 50 { | ||
True -> progress.finish(bar) | ||
False -> progress.tick(bar) | ||
} | ||
progress.print_bar(bar) | ||
sleep(15) | ||
do_something(bar, count + 1) | ||
} | ||
False -> Nil | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/// Print this code to clear the whole screen. | ||
pub const clear_screen_code = "\u{001b}[2J" | ||
|
||
/// Print this code to clear the current line. | ||
pub const clear_line_code = "\u{001b}[2K" | ||
|
||
/// Print this code to return the cursor to the "home" position. | ||
pub const return_home_code = "\u{001b}[H" | ||
|
||
/// Print this code to return to the start of the line | ||
pub const return_line_start_code = "\r" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
import gleam/io | ||
import gleam/string | ||
import gleam/string_builder.{type StringBuilder} | ||
|
||
import glitzer/codes | ||
|
||
/// A `String` with only one character. | ||
pub opaque type Char { | ||
Char(char: String) | ||
} | ||
|
||
/// Create a `Char` from a `String`. Returns a `Char` with the given string if | ||
/// the strings length is equal to one and a `Char` of "#" otherwise. | ||
/// | ||
/// <details> | ||
/// <summary>Example:<summary> | ||
/// | ||
/// ```gleam | ||
/// import glitzer/progress | ||
/// | ||
/// fn example() { | ||
/// let char = progress.char_from_string("A") | ||
/// } | ||
/// ``` | ||
pub fn char_from_string(from in: String) -> Char { | ||
let len = string.length(in) | ||
|
||
case len { | ||
1 -> Char(in) | ||
_ -> Char("#") | ||
} | ||
} | ||
|
||
pub fn string_from_char(from in: Char) -> String { | ||
in.char | ||
} | ||
|
||
pub opaque type State { | ||
State(progress: Int) | ||
} | ||
|
||
/// The style of a progress bar. | ||
pub opaque type ProgressStyle { | ||
ProgressStyle( | ||
left: String, | ||
right: String, | ||
empty: Char, | ||
fill: Char, | ||
length: Int, | ||
state: State, | ||
) | ||
} | ||
|
||
/// Create and return a default style for a progress bar. | ||
pub fn default_bar() -> ProgressStyle { | ||
ProgressStyle( | ||
left: "[", | ||
right: "]", | ||
empty: Char(" "), | ||
fill: Char("#"), | ||
length: 100, | ||
state: State(progress: 0), | ||
) | ||
} | ||
|
||
/// Create a new (completely empty) progress bar. | ||
/// | ||
/// <details> | ||
/// <summary>Example:<summary> | ||
/// | ||
/// ```gleam | ||
/// import glitzer/progress | ||
/// | ||
/// fn example() { | ||
/// let bar = | ||
/// progress.new_bar() | ||
/// |> progress.with_length(50) | ||
/// |> progress.with_left_text("Progress: ") | ||
/// |> progress.with_fill(progress.char_from_string("+")) | ||
/// } | ||
/// ``` | ||
pub fn new_bar() -> ProgressStyle { | ||
ProgressStyle( | ||
left: "", | ||
right: "", | ||
empty: Char(" "), | ||
fill: Char(" "), | ||
length: 0, | ||
state: State(progress: 0), | ||
) | ||
} | ||
|
||
/// Add left text to a progress bar. | ||
pub fn with_left_text( | ||
bar bar: ProgressStyle, | ||
left text: String, | ||
) -> ProgressStyle { | ||
ProgressStyle(..bar, left: text) | ||
} | ||
|
||
/// Add right text to a progress bar. | ||
pub fn with_right_text( | ||
bar bar: ProgressStyle, | ||
right text: String, | ||
) -> ProgressStyle { | ||
ProgressStyle(..bar, right: text) | ||
} | ||
|
||
/// Add a character to a progress bar that is used to represent the | ||
/// "background" of the bar. | ||
pub fn with_empty(bar bar: ProgressStyle, empty char: Char) -> ProgressStyle { | ||
ProgressStyle(..bar, empty: char) | ||
} | ||
|
||
/// Add a character to a progress bar that is used to fill the bar on each | ||
/// tick. | ||
pub fn with_fill(bar bar: ProgressStyle, fill char: Char) -> ProgressStyle { | ||
ProgressStyle(..bar, fill: char) | ||
} | ||
|
||
/// Add length to a progress bar. | ||
pub fn with_length(bar bar: ProgressStyle, length len: Int) -> ProgressStyle { | ||
ProgressStyle(..bar, length: len) | ||
} | ||
|
||
/// Increase the progress of the bar by one. | ||
pub fn tick(bar bar: ProgressStyle) -> ProgressStyle { | ||
ProgressStyle(..bar, state: State(progress: bar.state.progress + 1)) | ||
} | ||
|
||
/// Completely fill the progress bar. | ||
pub fn finish(bar bar: ProgressStyle) -> ProgressStyle { | ||
ProgressStyle(..bar, state: State(progress: bar.length + 1)) | ||
} | ||
|
||
/// Print the progress bar to stderr. | ||
/// | ||
/// <details> | ||
/// <summary>Example:<summary> | ||
/// | ||
/// ```gleam | ||
/// import glitzer/progress | ||
/// | ||
/// fn example() { | ||
/// let bar = progress.default_bar() | ||
/// | ||
/// run_example(bar, 0) | ||
/// } | ||
/// | ||
/// fn run_example(bar, count) { | ||
/// case count < 100 { | ||
/// True -> { | ||
/// let bar = progress.tick(bar) | ||
/// // do some awesome stuff :3 | ||
/// progress.print_bar(bar) | ||
/// run_example(bar, count + 1) | ||
/// } | ||
/// False -> Nil | ||
/// } | ||
/// } | ||
/// ``` | ||
pub fn print_bar(bar bar: ProgressStyle) { | ||
let fill = | ||
build_progress_fill(string_builder.new(), bar, bar.state.progress, 0) | ||
|> string_builder.to_string | ||
|
||
io.print_error( | ||
codes.clear_line_code | ||
<> codes.return_line_start_code | ||
<> bar.left | ||
<> fill | ||
<> bar.right, | ||
) | ||
} | ||
|
||
fn build_progress_fill( | ||
fill: StringBuilder, | ||
bar: ProgressStyle, | ||
left_nonempty: Int, | ||
count: Int, | ||
) -> StringBuilder { | ||
let fill = case left_nonempty > 0 { | ||
True -> string_builder.append(fill, bar.fill.char) | ||
False -> string_builder.append(fill, bar.empty.char) | ||
} | ||
|
||
case bar.length > count { | ||
True -> build_progress_fill(fill, bar, left_nonempty - 1, count + 1) | ||
False -> fill | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
-module(glitzer_ffi). | ||
|
||
% Public API | ||
-export([sleep/1]). | ||
|
||
sleep(Int) -> | ||
timer:sleep(Int). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export function sleep(ms = 0) { | ||
return new Promise(resolve => setTimeout(resolve, ms)); | ||
} |