Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

working with + operator

  • Loading branch information...
commit 019fae52845ac6205562bd845f586cb0bc083679 1 parent 3bd5901
Anders Conbere authored
View
39 src/main/scala/Bot.scala
@@ -3,16 +3,51 @@ package org.conbere.irc
import Messages._
import Tokens._
+object Implicits {
+ implicit class AddableOption(a:Option[Response]) {
+ def + (b:Option[Response]) =
+ (a,b) match {
+ case (None, None) =>None
+ case (x@Some(_), None) => x
+ case (None, y@Some(_)) => y
+ case (Some(x), Some(y)) => Some(x + y)
+ }
+ }
+}
+
trait Bot {
+ import Implicits._
+
+ type MessageHandler = PartialFunction[Message,Option[Response]]
+ // a list of channels to join
val rooms:List[Room]
- val respondTo:PartialFunction[Message,Option[Response]]
+ // a Partial function that matches against Message instances
+ // and returns Option[Message]
+ val respondTo:MessageHandler
+
+ // generally speaking this is something like authenticating to the server
val onConnect:Option[Response] = None
- val defaultResponse:PartialFunction[Message,Option[Response]] = {
+ // some default behaviors that most bots will want to implement
+ val defaultResponse:MessageHandler = {
case Ping(from) =>
Some(Pong(from))
case msg@Mode(params) if !rooms.isEmpty =>
Some(Join(rooms))
}
+
+ // helper for building respondTo
+ def handleMessage(handler:MessageHandler):MessageHandler = handler
+
+ def and(handlers:MessageHandler*):MessageHandler =
+ new PartialFunction[Message, Option[Response]] {
+ def apply(m:Message) =
+ handlers.foldLeft[Option[Response]](None) {
+ (acc, r) => acc + r.lift(m).getOrElse(None)
+ }
+
+ def isDefinedAt(m:Message) =
+ handlers.find { h => h.isDefinedAt(m) }.nonEmpty
+ }
}
View
4 src/main/scala/ClassicBot.scala
@@ -12,8 +12,8 @@ trait ClassicBot extends Bot {
val hostName = java.net.InetAddress.getLocalHost.getHostName
override val onConnect =
- Some(Pass(password) ++=
- Nick(nickName) ++=
+ Some(Pass(password) +
+ Nick(nickName) +
User(userName, hostName, serverName, realName))
}
View
13 src/main/scala/ExampleBot.scala
@@ -1,6 +1,6 @@
package org.conbere.irc
-import Tokens.{ Message, Response }
+import Tokens.Message
import Messages._
import akka.actor._
import com.typesafe.scalalogging.log4j.Logging
@@ -12,14 +12,19 @@ class ExampleBot( val serverName:String
, val realName:String
, val rooms:List[Room])
extends ClassicBot with Logging {
- val respondTo = defaultResponse.orElse[Message,Option[Response]] {
+ val before = handleMessage {
case PrivMsg(from, `nickName`, text) =>
Some(PrivMsg(from, text))
case PrivMsg(from, to, text) =>
None
- case _ =>
- None
}
+
+ val after = handleMessage {
+ case Ping(from) =>
+ Some(PrivMsg("#chan", "hey"))
+ }
+
+ val respondTo = and(defaultResponse, before, after)
}
object Main extends Logging {
View
15 src/main/scala/MessageCollection.scala
@@ -0,0 +1,15 @@
+package org.conbere.irc
+
+import akka.util.ByteStringBuilder
+import ControlChars._
+
+import Tokens.Message
+
+class ResponseCollection(val responseList:List[Response]=List())
+extends Response {
+ def +(r:Response) = new ResponseCollection(responseList :+ r )
+
+ val byteString = responseList.foldLeft(new ByteStringBuilder) {
+ (acc, m) => acc ++= m.byteString ++= CRLF
+ }.result
+}
View
9 src/main/scala/NullMessage.scala
@@ -0,0 +1,9 @@
+package org.conbere.irc
+
+import akka.util.ByteString
+import Tokens.Message
+
+class NullMessage extends Response {
+ def +(r:Response) = new ResponseCollection(List(r))
+ val byteString = ByteString("")
+}
View
10 src/main/scala/Response.scala
@@ -0,0 +1,10 @@
+package org.conbere.irc
+
+import akka.util.ByteString
+
+import Tokens.Message
+
+trait Response {
+ def +(r:Response):ResponseCollection
+ val byteString:ByteString
+}
View
15 src/main/scala/Tokens.scala
@@ -27,14 +27,9 @@ object Tokens {
host.getOrElse("")).mkString(" "))
}
- trait Response {
- def ++=(msg:Message):MessageCollection
- val byteString:ByteString
- }
-
case class Message(prefix:Option[Prefix], command:Command, params:List[String])
extends Token with Response {
- def ++=(m:Message) = new MessageCollection(List(this, m))
+ def +(r:Response) = new ResponseCollection(List(this, r))
def mkPrefixByteString(prefix:Option[Prefix]) =
prefix.map { p => p.byteString }.getOrElse(ByteString(""))
@@ -63,12 +58,4 @@ object Tokens {
SP ++=
ByteString(mkParamsString(params))).result
}
-
- class MessageCollection(val ml:List[Message])
- extends Token with Response {
- def ++=(m:Message) = new MessageCollection(ml :+ m )
- val byteString = ml.foldLeft(new ByteStringBuilder) {
- (acc, m) => acc ++= m.byteString ++= CRLF
- }.result
- }
}
Please sign in to comment.
Something went wrong with that request. Please try again.