require "date" def validate(*a) # Check arguments against either a list of acceptable classes or just a class raise ArgumentError, "expected an even number of arguments" if a.count%2 != 0 for i in (0..a.count-1).step(2) do if a[i+1].kind_of?(Class) then raise TypeError, "expected argument #{i/2} of type #{a[i+1].to_s}" unless a[i].kind_of?(a[i+1]) elsif a[i+1].kind_of?(Array) then raise TypeError, "expected argument #{i/2} of any of the types #{a[i+1].to_s}" unless a[i+1].include?(a[i].class) end end end module Heimdall # Core protocol class NetEntity # Abstraction that stores basic object properties @createdAt def initialize() @createdAt = DateTime.new end attr_reader :createdAt end class User < NetEntity # User abstraction (not bound to a group chat) @username @nickname def initialize(username,nickname = nil) validate( username, String, nickname, [String,NilClass] ) super() nickname = username if not nickname @username = username @nickname = nickname end attr_reader :username attr_accessor :nickname end class Channel < NetEntity # Channel abstraction (not bound to a group) # Practically acts as a message stack # Read access to all elements # Write access only to top @messages def initialize() validate( id, String ) super() @messages = [] end def [](index) @messages[id] end def <<(message) @messages.append(message) end def top(count = 1) return @messages[-1] if count == 1 @messages[(-1*count)..-1] end def filter(&block) @messages.filter(block) end def snapshot() @messages.clone end end class Message < NetEntity # Message abstraction with edits and content history (not bound to a group) @content @author @editedAt @contentHist def initialize(content,author,channel) validate( content, String, author, Heimdall::User, channel, Heimdall::Channel ) super() @editedAt = DateTime.new @contentHist = [content] @content = content @author = author end def edit(content) @content = content @editedAt = DateTime.new @contentHist.append(content) end attr_reader :content attr_reader :author attr_reader :contentHist attr_reader :editedAt end end