package rest

type IApplication interface {
	Executer(r IRequestIn) (IExecuter, bool)
}

type IApplicationStream interface {
	IApplication
	Connect() chan<- IStream
}

///////////////////////////////////////////////

type IValidator interface {
	Validate(r IRequestIn) IRequestOut
}

type IExecuter interface {
	Execute(r IRequestIn) IRequestOut
}

type ICommand interface {
	IValidator
	IExecuter
}

///////////////////////////////////////////////

func NewCommand(validator IValidator, executer IExecuter) *Command {
	return &Command{
		validator,
		executer,
	}
}

type Command struct {
	validator IValidator
	executer  IExecuter
}

func (s *Command) Validate(r IRequestIn) IRequestOut {
	return s.validator.Validate(r)
}

func (s *Command) Execute(r IRequestIn) IRequestOut {
	return s.executer.Execute(r)
}

///////////////////////////////////////////////

func NewValidator(method func(r IRequestIn) IRequestOut) *Validator {
	return &Validator{
		method,
	}
}

type Validator struct {
	method func(r IRequestIn) IRequestOut
}

func (s *Validator) Validate(r IRequestIn) IRequestOut {
	return s.method(r)
}

///////////////////////////////////////////////

func NewExecuter(method func(r IRequestIn) IRequestOut) *Executer {
	return &Executer{
		method,
	}
}

type Executer struct {
	method func(r IRequestIn) IRequestOut
}

func (s *Executer) Execute(r IRequestIn) IRequestOut {
	return s.method(r)
}