Skip to main content

TL;DR

I have no time to read tons of docs.
Just show me an example use case and I'll quickly craft something similar 😎.

— A lazy developer

# Any source code in the project.
def read_file_content(path)
result = ReadFileContent.result(path: path)

if result.success?
##
# Service tried to read the file content and completed it.
#
result.data[:content] # File content.
elsif result.failure?
##
# Service tried to read file content but did NOT complete it due to some expected reason.
#
App.logger.warn { result.message.to_s }

"" # Fallback value or any other reasonable fallback behavior.
else # result.error?
##
# Service NOT even tried to read file content due to a validation issue or exception.
#
App.logger.error { result.message.to_s }

raise VerboseException, result.message.to_s # Self-explanatory exception or any other reasonable fallback behavior.
end
end
require "convenient_service"
module ApplicationService
module Config
include ConvenientService::Concern

included do
include ConvenientService::Standard::Config
end
end
end
class AssertFileExists
include ApplicationService::Config

attr_reader :path

def initialize(path:)
@path = path
end

def result
return error("Path is `nil`") if path.nil?
return error("Path is empty") if path.empty?

return failure("File does not exist at path `#{path}`") unless ::File.exist?(path)

success
end
end
result = AssertFileExists.result(path: "Gemfile")
class AssertFileNotEmpty
include ApplicationService::Config

attr_accessor :path

def initialize(path:)
@path = path
end

def result
return error("Path is `nil`") if path.nil?
return error("Path is empty") if path.empty?

return failure("File is empty at path `#{path}`") if ::File.zero?(path)

success
end
end
result = AssertFileNotEmpty.result(path: "Gemfile")
class ReadFileContent
include ApplicationService::Config

attr_reader :path

step :validate_path
step AssertFileExists, in: :path
step AssertFileNotEmpty, in: :path
step :result, in: :path, out: :content

def initialize(path:)
@path = path
end

def result
success(content: ::File.read(path))
end

private

def validate_path
return error("Path is `nil`") if path.nil?
return error("Path is empty") if path.empty?

success
end
end
result = ReadFileContent.result(path: "Gemfile")

More examples​

Source CodeRSpec Specs
lib/convenient_service/examplesspec/lib/convenient_service