Skip to content

Commit

Permalink
Add SpinnerUI protocol (#41)
Browse files Browse the repository at this point in the history
* Add SpinnerUI protocol

* Replace print with ui print

* Fix print
  • Loading branch information
yury authored Mar 25, 2022
1 parent 2e782e2 commit 48eddae
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 14 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.build/
*.xcodeproj
Package.resolved
Package.resolved
.swiftpm/
49 changes: 36 additions & 13 deletions Sources/Spinner/Spinner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,32 @@ import Dispatch
import Rainbow
import Signals

struct StdOutSpinnerUI: SpinnerUI {
public func display(string: String) {
// Reset cursor to start of line
Swift.print("\r", terminator: "")
// Print the spinner frame and text
Swift.print(string, terminator: "")
// Flush STDOUT
fflush(stdout)
}

public func hideCursor() {
Swift.print("\u{001B}[?25l", terminator: "")
fflush(stdout)
}

public func unhideCursor() {
Swift.print("\u{001B}[?25h", terminator: "")
fflush(stdout)
}

public func printString(_ str: String) {
Swift.print(str, terminator: "")
fflush(stdout)
}
}

public final class Spinner {

/// Pattern holding frames to be animated
Expand All @@ -28,6 +54,8 @@ public final class Spinner {
var timestamp: Now?
/// Format of the Spinner
var format: String

let ui: SpinnerUI

/**
Create new spinner
Expand All @@ -38,7 +66,7 @@ public final class Spinner {
- Parameter color: Color - The color the animated pattern will render as - default is white
- Parameter: format: String - The format of the spinner - default is "{S} {T}"
*/
public init(_ pattern: SpinnerPattern, _ text: String = "", speed: Double? = nil, color: Color = .default, format: String = "{S} {T}") {
public init(_ pattern: SpinnerPattern, _ text: String = "", speed: Double? = nil, color: Color = .default, format: String = "{S} {T}", ui: SpinnerUI? = nil) {
self.pattern = pattern
self.text = text
self.speed = speed ?? pattern.defaultSpeed
Expand All @@ -48,6 +76,7 @@ public final class Spinner {
self.frameIndex = 0
self.running = false
self.queue = DispatchQueue(label: "io.Swift.Spinner")
self.ui = ui ?? StdOutSpinnerUI()

Signals.trap(signal: .int) { _ in
print("\u{001B}[?25h", terminator: "")
Expand Down Expand Up @@ -99,7 +128,8 @@ public final class Spinner {
}
self.unhideCursor()
self.renderSpinner()
print(terminator: terminator)
// print(terminator)
self.ui.printString(terminator)
}

/**
Expand Down Expand Up @@ -234,30 +264,23 @@ public final class Spinner {
}

func renderSpinner() {

// Reset cursor to start of line
print("\r", terminator: "")
// Print the spinner frame and text
var renderString = self.format.replacingOccurrences(of: "{S}", with: self.currentFrame()).replacingOccurrences(of: "{T}", with: self.text)
// get duration
if let timestamp = self.timestamp {
let duration = Now() - timestamp
renderString = renderString.replacingOccurrences(of: "{D}", with: duration.timeString)
}
print(renderString, terminator: "")
// Flush STDOUT
fflush(stdout)
ui.display(string: renderString)

}

func hideCursor() {
print("\u{001B}[?25l", terminator: "")
fflush(stdout)
ui.hideCursor()
}

func unhideCursor() {
print("\u{001B}[?25h", terminator: "")
fflush(stdout)
ui.unhideCursor()
}

}
7 changes: 7 additions & 0 deletions Sources/Spinner/SpinnerUI.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

public protocol SpinnerUI {
func display(string: String)
func hideCursor()
func unhideCursor()
func printString(_ str: String)
}

0 comments on commit 48eddae

Please sign in to comment.