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 inverse ;
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 asterisk 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 )
26 irc-message new now >>timestamp
27 [ [ (>>trailing) ] [ (>>parameters) ] [ (>>command) ] tri ] keep ;
31 GENERIC: command-string>> ( irc-message -- string )
33 M: irc-message command-string>> ( irc-message -- string ) command>> ;
34 M: ping command-string>> ( ping -- string ) drop "PING" ;
35 M: join command-string>> ( join -- string ) drop "JOIN" ;
36 M: part command-string>> ( part -- string ) drop "PART" ;
37 M: quit command-string>> ( quit -- string ) drop "QUIT" ;
38 M: nick command-string>> ( nick -- string ) drop "NICK" ;
39 M: privmsg command-string>> ( privmsg -- string ) drop "PRIVMSG" ;
40 M: notice command-string>> ( notice -- string ) drop "NOTICE" ;
41 M: mode command-string>> ( mode -- string ) drop "MODE" ;
42 M: kick command-string>> ( kick -- string ) drop "KICK" ;
44 GENERIC: command-parameters>> ( irc-message -- seq )
46 M: irc-message command-parameters>> ( irc-message -- seq ) parameters>> ;
47 M: ping command-parameters>> ( ping -- seq ) drop { } ;
48 M: join command-parameters>> ( join -- seq ) drop { } ;
49 M: part command-parameters>> ( part -- seq ) channel>> 1array ;
50 M: quit command-parameters>> ( quit -- seq ) drop { } ;
51 M: nick command-parameters>> ( nick -- seq ) drop { } ;
52 M: privmsg command-parameters>> ( privmsg -- seq ) name>> 1array ;
53 M: notice command-parameters>> ( norice -- seq ) type>> 1array ;
54 M: kick command-parameters>> ( kick -- seq )
55 [ channel>> ] [ who>> ] bi 2array ;
56 M: mode command-parameters>> ( mode -- seq )
57 [ name>> ] [ channel>> ] [ mode>> ] tri 3array ;
59 GENERIC: (>>command-parameters) ( params irc-message -- )
61 M: irc-message (>>command-parameters) ( params irc-message -- ) 2drop ;
62 M: logged-in (>>command-parameters) ( params part -- ) [ first ] dip (>>name) ;
63 M: privmsg (>>command-parameters) ( params privmsg -- ) [ first ] dip (>>name) ;
64 M: notice (>>command-parameters) ( params notice -- ) [ first ] dip (>>type) ;
65 M: part (>>command-parameters) ( params part -- )
66 [ first ] dip (>>channel) ;
67 M: kick (>>command-parameters) ( params kick -- )
68 [ first2 ] dip [ (>>who) ] [ (>>channel) ] bi ;
69 M: names-reply (>>command-parameters) ( params names-reply -- )
70 [ [ first ] dip (>>who) ] [ [ third ] dip (>>channel) ] 2bi ;
71 M: mode (>>command-parameters) ( params mode -- )
72 { { [ [ 2array ] dip ] [ [ (>>mode) ] [ (>>name) ] bi ] }
73 { [ [ 3array ] dip ] [ [ (>>parameter) ] [ (>>mode) ] [ (>>name) ] tri ] }
78 GENERIC: irc-message>client-line ( irc-message -- string )
80 M: irc-message irc-message>client-line ( irc-message -- string )
82 [ command-parameters>> " " sjoin ]
83 [ trailing>> [ CHAR: : prefix ] [ "" ] if* ]
84 tri 3array " " sjoin ;
86 GENERIC: irc-message>server-line ( irc-message -- string )
88 M: irc-message irc-message>server-line ( irc-message -- string )
89 drop "not implemented yet" ;
92 ! ======================================
94 ! ======================================
96 : split-at-first ( seq separators -- before after )
97 dupd '[ _ member? ] find
102 : remove-heading-: ( seq -- seq ) dup ":" head? [ 1 tail ] when ;
104 : parse-name ( string -- string )
105 remove-heading-: "!" split-at-first drop ;
107 : split-prefix ( string -- string/f string )
109 [ remove-heading-: " " split1 ]
113 : split-trailing ( string -- string string/f )
116 : copy-message-in ( origin dest -- )
117 { [ [ parameters>> ] dip [ (>>command-parameters) ] [ (>>parameters) ] 2bi ]
118 [ [ line>> ] dip (>>line) ]
119 [ [ prefix>> ] dip (>>prefix) ]
120 [ [ command>> ] dip (>>command) ]
121 [ [ trailing>> ] dip (>>trailing) ]
122 [ [ timestamp>> ] dip (>>timestamp) ]
127 UNION: sender-in-prefix privmsg join part quit kick mode nick ;
128 GENERIC: irc-message-sender ( irc-message -- sender )
129 M: sender-in-prefix irc-message-sender ( sender-in-prefix -- sender )
130 prefix>> parse-name ;
132 : string>irc-message ( string -- object )
133 dup split-prefix split-trailing
134 [ [ blank? ] trim " " split unclip swap ] dip
135 now irc-message boa ;
137 : parse-irc-line ( string -- message )
141 { "NOTICE" [ notice ] }
142 { "001" [ logged-in ] }
143 { "433" [ nick-in-use ] }
144 { "353" [ names-reply ] }
148 { "PRIVMSG" [ privmsg ] }
153 } case new [ copy-message-in ] keep ;