]> gitweb.factorcode.org Git - factor.git/blob - extra/irc/messages/messages.factor
Merge branch 'master' of git://factorcode.org/git/factor
[factor.git] / extra / irc / messages / messages.factor
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 quotations ;
5 RENAME: join sequences => sjoin
6 EXCLUDE: sequences => join ;
7 IN: irc.messages
8
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: privmsg < irc-message name ;
16 TUPLE: kick < irc-message channel who ;
17 TUPLE: roomlist < irc-message channel names ;
18 TUPLE: nick-in-use < irc-message asterisk name ;
19 TUPLE: notice < irc-message type ;
20 TUPLE: mode < irc-message channel mode ;
21 TUPLE: names-reply < irc-message who = channel ;
22 TUPLE: unhandled < irc-message ;
23
24 : <irc-client-message> ( command parameters trailing -- irc-message )
25     irc-message new now >>timestamp
26     [ [ (>>trailing) ] [ (>>parameters) ] [ (>>command) ] tri ] keep ;
27
28 <PRIVATE
29
30 GENERIC: irc-command-string ( irc-message -- string )
31
32 M: irc-message irc-command-string ( irc-message -- string ) command>> ;
33 M: ping        irc-command-string ( ping -- string )    drop "PING" ;
34 M: join        irc-command-string ( join -- string )    drop "JOIN" ;
35 M: part        irc-command-string ( part -- string )    drop "PART" ;
36 M: quit        irc-command-string ( quit -- string )    drop "QUIT" ;
37 M: privmsg     irc-command-string ( privmsg -- string ) drop "PRIVMSG" ;
38 M: notice      irc-command-string ( notice -- string )  drop "NOTICE" ;
39 M: mode        irc-command-string ( mode -- string )    drop "MODE" ;
40 M: kick        irc-command-string ( kick -- string )    drop "KICK" ;
41
42 GENERIC: irc-command-parameters ( irc-message -- seq )
43
44 M: irc-message irc-command-parameters ( irc-message -- seq ) parameters>> ;
45 M: ping        irc-command-parameters ( ping -- seq )    drop { } ;
46 M: join        irc-command-parameters ( join -- seq )    drop { } ;
47 M: part        irc-command-parameters ( part -- seq )    name>> 1array ;
48 M: quit        irc-command-parameters ( quit -- seq )    drop { } ;
49 M: privmsg     irc-command-parameters ( privmsg -- seq ) name>> 1array ;
50 M: notice      irc-command-parameters ( norice -- seq )  type>> 1array ;
51 M: kick irc-command-parameters ( kick -- seq )
52     [ channel>> ] [ who>> ] bi 2array ;
53 M: mode irc-command-parameters ( mode -- seq )
54     [ name>> ] [ channel>> ] [ mode>> ] tri 3array ;
55
56 PRIVATE>
57
58 GENERIC: irc-message>client-line ( irc-message -- string )
59
60 M: irc-message irc-message>client-line ( irc-message -- string )
61     [ irc-command-string ]
62     [ irc-command-parameters " " sjoin ]
63     [ trailing>> [ CHAR: : prefix ] [ "" ] if* ]
64     tri 3array " " sjoin ;
65
66 GENERIC: irc-message>server-line ( irc-message -- string )
67
68 M: irc-message irc-message>server-line ( irc-message -- string )
69    drop "not implemented yet" ;
70
71 <PRIVATE
72 ! ======================================
73 ! Message parsing
74 ! ======================================
75
76 : split-at-first ( seq separators -- before after )
77     dupd '[ , member? ] find
78         [ cut 1 tail ]
79         [ swap ]
80     if ;
81
82 : remove-heading-: ( seq -- seq ) dup ":" head? [ 1 tail ] when ;
83
84 : parse-name ( string -- string )
85     remove-heading-: "!" split-at-first drop ;
86
87 : split-prefix ( string -- string/f string )
88     dup ":" head?
89         [ remove-heading-: " " split1 ]
90         [ f swap ]
91     if ;
92
93 : split-trailing ( string -- string string/f )
94     ":" split1 ;
95
96 PRIVATE>
97
98 : string>irc-message ( string -- object )
99     dup split-prefix split-trailing
100     [ [ blank? ] trim " " split unclip swap ] dip
101     now irc-message boa ;
102
103 : parse-irc-line ( string -- message )
104     string>irc-message
105     dup command>> {
106         { "PING" [ ping ] }
107         { "NOTICE" [ notice ] }
108         { "001" [ logged-in ] }
109         { "433" [ nick-in-use ] }
110         { "353" [ names-reply ] }
111         { "JOIN" [ join ] }
112         { "PART" [ part ] }
113         { "PRIVMSG" [ privmsg ] }
114         { "QUIT" [ quit ] }
115         { "MODE" [ mode ] }
116         { "KICK" [ kick ] }
117         [ drop unhandled ]
118     } case
119     [ [ tuple-slots ] [ parameters>> ] bi append ] dip
120     [ all-slots over [ length ] bi@ min head >quotation ] keep
121     '[ @ , boa nip ] call ;