cyclecmd

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 7, 2024 License: Apache-2.0 Imports: 9 Imported by: 0

README

cyclecmd

Description

cyclecmd helps you to write console applications based on events that are triggered by the user input. It is an unopinionated library, thus you can define events in any way that you need.

How to get it

You can get cyclecmd with the following command:

go get github.com/RaphSku/cyclecmd@latest

How to use it

First of all, you have to define a default event that will be triggered by any user input that does not trigger any other registered event. For this example, let's print the user input (that we call token) on our default event.

type DefaultEvent struct{}

func (de *DefaultEvent) Handle(token string) error {
	fmt.Print(token)
	return nil
}

Note, that all events have to comply with the following interface:

type Event interface {
    Handle(token string) error
}

The default event is the only event that we are required to create, because we can initialize the event registry with this event:

defaultEventInformation := cyclecmd.EventInformation{
    EventName: "Default",
    Event:     &DefaultEvent{},
}
eventRegistry := cyclecmd.NewEventRegistry(defaultEventInformation)

For demonstration purposes, let us register another event, the backspace event that will print a backspace for us.

type BackspaceEvent struct{}

func (be *BackspaceEvent) Handle(token string) error {
	fmt.Print("\b \b")
	return nil
}

backspaceEventInformation := cyclecmd.EventInformation{
    EventName: "Backspace",
    Event:     &BackspaceEvent{},
}
eventRegistry.RegisterEvent("\x7f", backspaceEventInformation)

Next, we need to initialize the event history, this is relatively simple:

eventHistory := cyclecmd.NewEventHistory()

And with the event registry and event history we can finally initialise our console app and let it run and handle our custom events.

consoleApp := cyclecmd.NewConsoleApp(
    context.Background(),
    "Test",
    "v0.1.0",
    "Example description...",
    eventRegistry,
    eventHistory,
)
consoleApp.SetLineDelimiter("\n\r>>> ", "\x7f")
consoleApp.Start()

Note, that we can also set a line delimiter that will print in our case "\n\r>>> ". Be ware, that you have to add "\n\r" to the delimiter if you want to print a new line where each line begins with >>>. This is intentional, such that you can define any delimiter that you want, even ones with no new lines if that is what you require. The Start() method will kick off the event loop.

Example Projects

If you want to see a complete example on how to leverage cyclecmd, please have a look at the following projects that use cyclecmd:

Documentation

Overview

Package cyclecmd is an unopinionated library for building your own console applications.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ConsoleApp

type ConsoleApp struct {

	// Name of the console application
	Name string
	// Version of the console application
	Version string
	// Description of the console application. Should be relatively short.
	Description string
	// Delimiter can be used to visibly separate lines in your console application.
	// But the usage is flexible.
	Delimiter string
	// DelimiterEventTrigger defines when a Delimiter will be printed.
	DelimiterEventTrigger string
	// Should be only used when you want to pause your console application for some reason.
	ControlC chan bool
	// contains filtered or unexported fields
}

ConsoleApp handles all the events in an event loop and serves as an entry point for your console.

func NewConsoleApp

func NewConsoleApp(
	ctx context.Context,
	name string,
	version string,
	description string,
	eventRegistry *EventRegistry,
	eventHistory *EventHistory,
) *ConsoleApp

NewConsoleApp initializes a new Console App instance that will be the main entry point to your console application or to be more specific, to the event loop that will handle the custom events.

Parameters:

  • `ctx` : Context that will be propagated to the event loop
  • `name` : Name of the Console App
  • `version` : Version of the Console App
  • `description` : Description of the Console App. Should be relatively short
  • `eventRegistry` : The single source of truth for custom events that were registered
  • `eventHistory` : Records events that were processed

Returns:

  • `*ConsoleApp` : An instance of a Console Application

func (*ConsoleApp) ChangeToDebugMode

func (ca *ConsoleApp) ChangeToDebugMode()

ChangeToDebugMode allows you to switch to debug mode for logging. Don't forget to switch off debug mode once you want to ship your console app to production since all logs will be otherwise shown.

func (*ConsoleApp) SetLineDelimiter

func (ca *ConsoleApp) SetLineDelimiter(delimiter string, eventTrigger string)

SetLineDelimiter allows the User to define a custom delimiter that will be printed after each event that is defined by eventTrigger.

Parameters:

  • `delimiter` : Delimiter should be fairly short.
  • `eventTrigger` : Delimiter will be printed after each event that is triggered by eventTrigger

func (*ConsoleApp) Start

func (ca *ConsoleApp) Start()

Start will save the terminal state, handle terminating signals and kick off the event loop. Note, events are recorded in the event history before the event handling happens. They are recorded as they occur.

type Event

type Event interface {
	Handle(token string) error
}

Event is an interface that defines the behavior of the custom events that the User can define themselves.

Event expects the following method to be implemented by all events:

Behavior:

  • `Handle(token string) error` : it expects the token that is associated with the event

type EventHistory

type EventHistory struct {
	// contains filtered or unexported fields
}

EventHistory records events and offers behavior to manipulate the history and to read events from history.

func NewEventHistory

func NewEventHistory() *EventHistory

NewEventHistory initialises an event history instance that can be used to record past events.

Returns:

  • `*EventHistory` : Returns an instance of EventHistory

func (*EventHistory) AddEvent

func (eh *EventHistory) AddEvent(eventEntry EventHistoryEntry)

AddEvent will add an event to the history.

Parameters:

  • `eventEntry` : Entry that will be recorded and contains all information related to an event.

func (*EventHistory) GetLastEventsFromHistoryToEventReference

func (eh *EventHistory) GetLastEventsFromHistoryToEventReference(eventName string) []string

GetLastEventsFromHistoryToEventReference will return all event names that followed after a specific event happened.

Parameters:

  • `eventName` : The name of the event that serves as a reference

Returns:

  • `[]string` : Returns a series of event names that happened after the reference event

func (*EventHistory) Len

func (eh *EventHistory) Len() int

Len returns the number of events that has been recorded.

Returns:

  • `int` : Number of events

func (*EventHistory) MostRecentSpliceEventsOfHistory

func (eh *EventHistory) MostRecentSpliceEventsOfHistory(eventName string) []EventHistoryEntry

MostRecentSpliceEventsOfHistory will return a range of events that occured between some event that is specified by eventName.

Parameters:

  • `eventName` : Name of the reference event

Returns:

  • `[]EventHistoryEntry` : Sequence of event history entries

func (*EventHistory) PrintLastEventHistoryEntries

func (eh *EventHistory) PrintLastEventHistoryEntries(n int)

PrintLastEventHistoryEntries will print information related to the last n events that were recorded.

Parameters:

  • `n` : Number of events

func (*EventHistory) RemoveNthEventFromHistory

func (eh *EventHistory) RemoveNthEventFromHistory(n int)

RemoveNthEventFromHistory removes the nth event from the history. If the nth element does not exist, nothing will happen.

Parameters:

  • `n` : nth event that should be removed from history

func (*EventHistory) RetrieveEventEntryByIndex

func (eh *EventHistory) RetrieveEventEntryByIndex(index int) (EventHistoryEntry, error)

RetrieveEventEntryByIndex will return the event entry at index position

Parameters:

  • `index` : Position in the event history that you want to access

Returns:

  • `EventHistoryEntry` : The event history entry at index position
  • `error` : Returns an error when there is no event history entry at position index

type EventHistoryEntry

type EventHistoryEntry struct {
	// Token is the same as event trigger
	Token string
	// The name of the event
	EventName string
	// The event instance itself
	Event Event
}

EventHistoryEntry stores the event and the event name but also the token that triggered the event. This is especially useful for the DefaultEvent since that event gets triggered by every token that is not already registered with another event.

type EventInformation

type EventInformation struct {
	// Name of the event
	EventName string
	// The event instance itself
	Event Event
}

EventInformation stores the event itself but also the event name that was given to the custom event.

type EventRegistry

type EventRegistry struct {

	// DefaultEventInformation contains information related to the default event that is triggered whenever
	// a token does not match with any other event that is registered.
	DefaultEventInformation EventInformation
	// contains filtered or unexported fields
}

EventRegistry contains all related information with custom events that are registered with this registry.

func NewEventRegistry

func NewEventRegistry(defaultEventInformation EventInformation) *EventRegistry

NewEventRegistry initialises the event registry.

Parameters:

  • `defaultEventInformation` : Information related to the default event

Returns:

  • `*EventRegistry` - Returns an instance of the event registry

func (*EventRegistry) GetMatchingEventInformation

func (er *EventRegistry) GetMatchingEventInformation(eventTrigger string) (EventInformation, error)

GetMatchingEventInformation retrieves the information related to the event that gets triggered by `eventTrigger`. The default event is returned when the event trigger matches no event registered in the event registry.

Parameters:

  • `eventTrigger` : Trigger for the event that should be returned

Returns:

  • `EventInformation` : Information related to the event triggered by `eventTrigger`
  • `error` : An error is only returned when no default event is defined

func (*EventRegistry) RegisterEvent

func (er *EventRegistry) RegisterEvent(eventTrigger string, eventInformation EventInformation) error

RegisterEvent registers an event with an event trigger.

Parameters:

  • `eventTrigger` : Trigger that will kick off the event
  • `eventInformation` : Information related to the event that will be triggered by `eventTrigger`

Returns:

  • `error` : Returns an error when the event is already registered

func (*EventRegistry) ResetEventRegistry

func (er *EventRegistry) ResetEventRegistry()

ResetEventRegistry resets the event registry, so all registered events are deleted from the registry.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL