Skip to content

Commit

Permalink
feat: iterators (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
miampf authored Jun 5, 2024
1 parent 96c385a commit 4b5dfaf
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 6 deletions.
38 changes: 34 additions & 4 deletions src/glitzer.gleam
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import gleam/int
import gleam/iterator

import glitzer/progress

@external(erlang, "glitzer_ffi", "sleep")
Expand All @@ -10,19 +13,46 @@ pub fn main() {
|> progress.with_length(10)

do_something(bar, 0)
do_something_else()
do_cool_shit_with_2_it()
}

fn do_something(bar, count) {
case count < 10 {
True -> {
let bar = case count > 5 {
True -> progress.finish(bar)
False -> progress.tick(bar)
}
let bar = progress.tick(bar)
progress.print_bar(bar)
sleep(100)
do_something(bar, count + 1)
}
False -> Nil
}
}

fn do_something_else() {
let bar =
progress.fancy_slim_arrow_bar()
|> progress.with_length(10)

iterator.range(0, 10)
|> progress.each_iterator(bar, fn(bar, i) {
progress.with_left_text(bar, int.to_string(i) <> " ")
|> progress.print_bar
sleep(100)
})
}

fn do_cool_shit_with_2_it() {
let bar =
progress.default_bar()
|> progress.with_length(10)
let i1 = iterator.range(0, 10)
let i2 = iterator.range(100, 150)
progress.map2_iterator(i1, i2, bar, fn(bar, e1, e2) {
progress.with_left_text(bar, int.to_string(e1) <> " ")
|> progress.with_right_text(" " <> int.to_string(e2))
|> progress.print_bar
sleep(100)
})
|> iterator.run
}
82 changes: 80 additions & 2 deletions src/glitzer/progress.gleam
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import gleam/io
import gleam/iterator.{type Iterator}
import gleam/option.{type Option}
import gleam/string
import gleam/string_builder.{type StringBuilder}
Expand Down Expand Up @@ -281,17 +282,28 @@ pub fn finish(bar bar: ProgressStyle) -> ProgressStyle {
/// }
/// ```
pub fn print_bar(bar bar: ProgressStyle) {
let bar =
ProgressStyle(
..bar,
state: State(..bar.state, finished: bar.state.progress >= bar.length),
)
let fill =
build_progress_fill(string_builder.new(), bar, bar.state.progress, 0)
build_progress_fill(string_builder.new(), bar, bar.state.progress + 1, 0)
|> string_builder.to_string

let end = case bar.state.finished {
True -> "\n"
False -> ""
}

io.print_error(
codes.hide_cursor_code
<> codes.clear_line_code
<> codes.return_line_start_code
<> bar.left
<> fill
<> bar.right,
<> bar.right
<> end,
)
}

Expand Down Expand Up @@ -356,3 +368,69 @@ fn get_finished_fill(fill: StringBuilder, bar: ProgressStyle) -> StringBuilder {
False -> string_builder.append(fill, bar.fill.char)
}
}

/// Map an iterator to a function with a bar that ticks every run of the
/// function.
///
/// <details>
/// <summary>Example:<summary>
///
/// ```gleam
/// import glitzer/progress
///
/// fn example(bar) {
/// iterator.range(0, 100)
/// |> progress.map_iterator(fn(bar, element) {
/// progress.print_bar(bar)
/// // do some heavy calculations here >:)
/// })
/// }
/// ```
pub fn map_iterator(
over i: Iterator(a),
bar bar: ProgressStyle,
with fun: fn(ProgressStyle, a) -> b,
) -> Iterator(b) {
iterator.index(i)
|> iterator.map(fn(pair) {
let #(el, i) = pair
tick_bar_by_i(bar, i)
|> fun(el)
})
}

fn tick_bar_by_i(bar, i) -> ProgressStyle {
case i > 0 {
True -> tick_bar_by_i(tick(bar), i - 1)
False -> bar
}
}

pub fn map2_iterator(
iterator1 i1: Iterator(a),
iterator2 i2: Iterator(b),
bar bar: ProgressStyle,
with fun: fn(ProgressStyle, a, b) -> c,
) -> Iterator(c) {
iterator.zip(i1, i2)
|> iterator.index
|> iterator.map(fn(pair) {
let #(pair, i) = pair
let #(el1, el2) = pair
tick_bar_by_i(bar, i)
|> fun(el1, el2)
})
}

pub fn each_iterator(
over i: Iterator(a),
bar bar: ProgressStyle,
with fun: fn(ProgressStyle, a) -> b,
) -> Nil {
iterator.index(i)
|> iterator.each(fn(pair) {
let #(el, i) = pair
tick_bar_by_i(bar, i)
|> fun(el)
})
}

0 comments on commit 4b5dfaf

Please sign in to comment.