package app import ( "fmt" "log/slog" ) // Subsystem represents a sub-system of the application, with its setup and // teardown functions and dependencies. type Subsystem struct { logger *slog.Logger name string setup setupFn teardown teardownFn depends []*Subsystem } // SubsystemOpts contains user-exposed options when defining a subsystem. type SubsystemOpts struct { // Setup is the setup function for the subsystem. Setup setupFn // Teardown is the teardown function for the subsystem. Teardown teardownFn // Depends is a list of subsystems that this subsystem depends on. Depends []*Subsystem } // NewSubsystem creates a new Subsystem instance with the given name and options. func NewSubsystem(name string, opts SubsystemOpts) *Subsystem { return &Subsystem{ name: name, setup: opts.Setup, teardown: opts.Teardown, depends: opts.Depends, } } // Logger returns the logger for the subsystem. func (s *Subsystem) Logger() *slog.Logger { if s.logger == nil { panic(fmt.Sprintf("subsytem %s used before logger was initialized", s.name)) } return s.logger }