up to date with .35 specs and standards

pull/64/head
Cooper Hammond 2020-08-31 14:35:22 -06:00
parent 4e1ce855eb
commit 10bd5fd969
7 changed files with 174 additions and 8 deletions

View File

@ -1,6 +1,10 @@
version: 1.0
version: 2.0
shards:
ydl_binaries:
github: cooperhammond/ydl-binaries
commit: c82e3937fee20fd076b1c73e24b2d0205e2cf0da
json_mapping:
git: https://github.com/crystal-lang/json_mapping.cr.git
version: 0.1.0
ydl_binaries:
git: https://github.com/cooperhammond/ydl-binaries.git
version: 1.1.1+git.commit.c82e3937fee20fd076b1c73e24b2d0205e2cf0da

View File

@ -1,5 +1,5 @@
name: irs
version: 1.0.0
version: 1.0.1
authors:
- Cooper Hammond <kepoorh@gmail.com>
@ -12,4 +12,6 @@ license: MIT
dependencies:
ydl_binaries:
github: cooperhammond/ydl-binaries
github: cooperhammond/ydl-binaries
json_mapping:
github: crystal-lang/json_mapping.cr

View File

@ -9,7 +9,7 @@ class Album < SpotifyList
# Uses the `spotify_searcher` defined in parent `SpotifyList` to find the
# correct metadata of the list
def find_it
def find_it : JSON::Any
album = @spotify_searcher.find_item("album", {
"name" => @list_name.as(String),
"artist" => @list_author.as(String),

View File

@ -1,4 +1,5 @@
require "json"
require "json_mapping"
class PlaylistExtensionMapper
JSON.mapping(

View File

@ -13,7 +13,7 @@ class Playlist < SpotifyList
# Uses the `spotify_searcher` defined in parent `SpotifyList` to find the
# correct metadata of the list
def find_it
def find_it : JSON::Any
@playlist = @spotify_searcher.find_item("playlist", {
"name" => @list_name.as(String),
"username" => @list_author.as(String),

157
src/interact/future.cr Normal file
View File

@ -0,0 +1,157 @@
# copy and pasted from crystal 0.33.1
# https://github.com/crystal-lang/crystal/blob/18e76172444c7bd07f58bf360bc21981b667668d/src/concurrent/future.cr#L138
# :nodoc:
class Concurrent::Future(R)
enum State
Idle
Delayed
Running
Completed
Canceled
end
@value : R?
@error : Exception?
@delay : Float64
def initialize(run_immediately = true, delay = 0.0, &@block : -> R)
@state = State::Idle
@value = nil
@error = nil
@channel = Channel(Nil).new
@delay = delay.to_f
@cancel_msg = nil
spawn_compute if run_immediately
end
def get
wait
value_or_raise
end
def success?
completed? && !@error
end
def failure?
completed? && @error
end
def canceled?
@state == State::Canceled
end
def completed?
@state == State::Completed
end
def running?
@state == State::Running
end
def delayed?
@state == State::Delayed
end
def idle?
@state == State::Idle
end
def cancel(msg = "Future canceled, you reached the [End of Time]")
return if @state >= State::Completed
@state = State::Canceled
@cancel_msg = msg
@channel.close
nil
end
private def compute
return if @state >= State::Delayed
run_compute
end
private def spawn_compute
return if @state >= State::Delayed
@state = @delay > 0 ? State::Delayed : State::Running
spawn { run_compute }
end
private def run_compute
delay = @delay
if delay > 0
sleep delay
return if @state >= State::Canceled
@state = State::Running
end
begin
@value = @block.call
rescue ex
@error = ex
ensure
@channel.close
@state = State::Completed
end
end
private def wait
return if @state >= State::Completed
compute
@channel.receive?
end
private def value_or_raise
raise Exception.new(@cancel_msg) if @state == State::Canceled
value = @value
if value.is_a?(R)
value
elsif error = @error
raise error
else
raise "compiler bug"
end
end
end
# Spawns a `Fiber` to compute *&block* in the background after *delay* has elapsed.
# Access to get is synchronized between fibers. *&block* is only called once.
# May be canceled before *&block* is called by calling `cancel`.
# ```
# d = delay(1) { Process.kill(Process.pid) }
# long_operation
# d.cancel
# ```
def delay(delay, &block : -> _)
Concurrent::Future.new delay: delay, &block
end
# Spawns a `Fiber` to compute *&block* in the background.
# Access to get is synchronized between fibers. *&block* is only called once.
# ```
# f = future { http_request }
# ... other actions ...
# f.get #=> String
# ```
def future(&exp : -> _)
Concurrent::Future.new &exp
end
# Conditionally spawns a `Fiber` to run *&block* in the background.
# Access to get is synchronized between fibers. *&block* is only called once.
# *&block* doesn't run by default, only when `get` is called.
# ```
# l = lazy { expensive_computation }
# spawn { maybe_use_computation(l) }
# spawn { maybe_use_computation(l) }
# ```
def lazy(&block : -> _)
Concurrent::Future.new run_immediately: false, &block
end

View File

@ -1,3 +1,5 @@
require "./future"
class Logger
@done_signal = "---DONE---"