1 ! Copyright (C) 2008 Bruno Deferrari
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: kernel fry splitting ascii calendar accessors combinators qualified
4 arrays classes.tuple math.order ;
5 RENAME: join sequences => sjoin
6 EXCLUDE: sequences => join ;
9 TUPLE: irc-message line prefix command parameters trailing timestamp ;
10 TUPLE: logged-in < irc-message name ;
11 TUPLE: ping < irc-message ;
12 TUPLE: join < irc-message ;
13 TUPLE: part < irc-message channel ;
14 TUPLE: quit < irc-message ;
15 TUPLE: nick < irc-message ;
16 TUPLE: privmsg < irc-message name ;
17 TUPLE: kick < irc-message channel who ;
18 TUPLE: roomlist < irc-message channel names ;
19 TUPLE: nick-in-use < irc-message name ;
20 TUPLE: notice < irc-message type ;
21 TUPLE: mode < irc-message name mode parameter ;
22 TUPLE: names-reply < irc-message who channel ;
23 TUPLE: unhandled < irc-message ;
25 : <irc-client-message> ( command parameters trailing -- irc-message )
34 GENERIC: command-string>> ( irc-message -- string )
36 M: irc-message command-string>> ( irc-message -- string ) command>> ;
37 M: ping command-string>> ( ping -- string ) drop "PING" ;
38 M: join command-string>> ( join -- string ) drop "JOIN" ;
39 M: part command-string>> ( part -- string ) drop "PART" ;
40 M: quit command-string>> ( quit -- string ) drop "QUIT" ;
41 M: nick command-string>> ( nick -- string ) drop "NICK" ;
42 M: privmsg command-string>> ( privmsg -- string ) drop "PRIVMSG" ;
43 M: notice command-string>> ( notice -- string ) drop "NOTICE" ;
44 M: mode command-string>> ( mode -- string ) drop "MODE" ;
45 M: kick command-string>> ( kick -- string ) drop "KICK" ;
47 GENERIC: command-parameters>> ( irc-message -- seq )
49 M: irc-message command-parameters>> ( irc-message -- seq ) parameters>> ;
50 M: ping command-parameters>> ( ping -- seq ) drop { } ;
51 M: join command-parameters>> ( join -- seq ) drop { } ;
52 M: part command-parameters>> ( part -- seq ) channel>> 1array ;
53 M: quit command-parameters>> ( quit -- seq ) drop { } ;
54 M: nick command-parameters>> ( nick -- seq ) drop { } ;
55 M: privmsg command-parameters>> ( privmsg -- seq ) name>> 1array ;
56 M: notice command-parameters>> ( norice -- seq ) type>> 1array ;
57 M: kick command-parameters>> ( kick -- seq )
58 [ channel>> ] [ who>> ] bi 2array ;
59 M: mode command-parameters>> ( mode -- seq )
60 [ name>> ] [ channel>> ] [ mode>> ] tri 3array ;
62 GENERIC# >>command-parameters 1 ( irc-message params -- irc-message )
64 M: irc-message >>command-parameters ( irc-message params -- irc-message )
67 M: logged-in >>command-parameters ( part params -- part )
70 M: privmsg >>command-parameters ( privmsg params -- privmsg )
73 M: notice >>command-parameters ( notice params -- notice )
76 M: part >>command-parameters ( part params -- part )
79 M: kick >>command-parameters ( kick params -- kick )
80 first2 [ >>channel ] [ >>who ] bi* ;
82 M: nick-in-use >>command-parameters ( nick-in-use params -- nick-in-use )
85 M: names-reply >>command-parameters ( names-reply params -- names-reply )
86 first3 nip [ >>who ] [ >>channel ] bi* ;
88 M: mode >>command-parameters ( mode params -- mode )
90 first3 [ >>name ] [ >>mode ] [ >>parameter ] tri*
92 first2 [ >>name ] [ >>mode ] bi*
97 GENERIC: irc-message>client-line ( irc-message -- string )
99 M: irc-message irc-message>client-line ( irc-message -- string )
101 [ command-parameters>> " " sjoin ]
102 [ trailing>> [ CHAR: : prefix ] [ "" ] if* ]
103 tri 3array " " sjoin ;
105 GENERIC: irc-message>server-line ( irc-message -- string )
107 M: irc-message irc-message>server-line ( irc-message -- string )
108 drop "not implemented yet" ;
112 ! ======================================
114 ! ======================================
116 : split-at-first ( seq separators -- before after )
117 dupd '[ _ member? ] find [ cut 1 tail ] [ swap ] if ;
119 : remove-heading-: ( seq -- seq )
122 : parse-name ( string -- string )
123 remove-heading-: "!" split-at-first drop ;
125 : split-prefix ( string -- string/f string )
127 [ remove-heading-: " " split1 ] [ f swap ] if ;
129 : split-trailing ( string -- string string/f )
132 : copy-message-in ( command irc-message -- command )
134 [ parameters>> [ >>parameters ] [ >>command-parameters ] bi ]
136 [ prefix>> >>prefix ]
137 [ command>> >>command ]
138 [ trailing>> >>trailing ]
139 [ timestamp>> >>timestamp ]
144 UNION: sender-in-prefix privmsg join part quit kick mode nick ;
145 GENERIC: irc-message-sender ( irc-message -- sender )
146 M: sender-in-prefix irc-message-sender ( sender-in-prefix -- sender )
147 prefix>> parse-name ;
149 : string>irc-message ( string -- object )
150 dup split-prefix split-trailing
151 [ [ blank? ] trim " " split unclip swap ] dip
152 now irc-message boa ;
154 : irc-message>command ( irc-message -- command )
158 { "NOTICE" [ notice ] }
159 { "001" [ logged-in ] }
160 { "433" [ nick-in-use ] }
161 { "353" [ names-reply ] }
165 { "PRIVMSG" [ privmsg ] }
171 ] keep copy-message-in ;
173 : parse-irc-line ( string -- message )
174 string>irc-message irc-message>command ;