~siegfriedehret/crystal-tuto

07d47e5dd404fe5da080ca620d918304a6c78402 — Siegfried Ehret 1 year, 8 months ago 6a6be72 partie-02
🎁 on bidouille pour la deuxième partie

tagzytout: partie-02
M src/cli.cr => src/cli.cr +7 -0
@@ 1,17 1,24 @@
require "option_parser"
require "./commands/*"
require "./lib/config"

module Myapp
  DEFAULT_COMMAND = "help"

  def self.run
    config = Config.new

    OptionParser.parse(ARGV) do |opts|
      opts.unknown_args do |args, options|
        command = args[0]? || DEFAULT_COMMAND

        case command
        when "add"
          Commands::Add.new(config, args[1..-1])
        when "help"
          Commands::Help.run
        when "show"
          Commands::Show.new(config, args[1..-1])
        when "version"
          Commands::Version.run
        else

A src/commands/add.cr => src/commands/add.cr +26 -0
@@ 0,0 1,26 @@
require "../lib/config"
require "../structs/*"

module Myapp
  module Commands
    class Add
      def initialize(@config : Config, args : Array(String))
        name = args.find { |el| el.starts_with? "name=" }

        emails = args
          .select { |el| el.starts_with? "email=" }
          .map { |el| el.split("=")[1] }

        add(name, emails)
      end

      def add(name : String | Nil, emails : Array(String))
        if name.nil?
          puts "We need a name!"
        else
          @config.add_contact Contact.new(name.split("=")[1], emails)
        end
      end
    end
  end
end

M src/commands/help.cr => src/commands/help.cr +4 -1
@@ 5,7 5,10 @@ module Myapp
        puts <<-HELP
      myapp <command> [<options>]

      TODO
      Available commands:

        add name=<name> email=<email>   To add a contact
        show <partial name>             To list matching contacts
     HELP

        exit

A src/commands/show.cr => src/commands/show.cr +21 -0
@@ 0,0 1,21 @@
require "../lib/config"

module Myapp
  module Commands
    class Show
      def initialize(@config : Config, args : Array(String))
        args.each do |contact_name|
          show contact_name
        end
      end

      private def show(contact_name : String)
        @config.contacts
          .select { |e| e.name.downcase.includes? contact_name.downcase }
          .each do |contact|
            contact.print
          end
      end
    end
  end
end

A src/lib/config.cr => src/lib/config.cr +32 -0
@@ 0,0 1,32 @@
require "yaml"
require "../structs/list"

module Myapp
  class Config
    @@config_path : Path = Path.home / "myapp.yaml"
    property list : List

    def initialize
      if File.exists? @@config_path
        @list = List.from_yaml(File.read(@@config_path))
      else
        @list = List.new

        save
      end
    end

    def contacts
      @list.contacts
    end

    def add_contact(contact : Contact)
      @list.contacts << contact
      save
    end

    private def save
      File.open(@@config_path, "w") { |f| @list.to_yaml(f) }
    end
  end
end

A src/structs/contact.cr => src/structs/contact.cr +22 -0
@@ 0,0 1,22 @@
require "yaml"

module Myapp
  struct Contact
    include YAML::Serializable
    property name : String
    property emails : Array(String)?

    def initialize(@name : String, @emails : Array(String)?)
    end

    def print
      emails = @emails

      puts "#{@name}: #{if emails.nil?
                          "no email found"
                        else
                          emails.join(", ")
                        end}"
    end
  end
end

A src/structs/list.cr => src/structs/list.cr +13 -0
@@ 0,0 1,13 @@
require "yaml"
require "./contact"

module Myapp
  struct List
    include YAML::Serializable
    property contacts : Array(Contact)

    def initialize
      @contacts = Array(Contact).new
    end
  end
end