source: code/trunk/irc.go@ 128

Last change on this file since 128 was 128, checked in by delthas, 5 years ago

Add WHOIS support

File size: 2.1 KB
Line 
1package soju
2
3import (
4 "fmt"
5 "strings"
6
7 "gopkg.in/irc.v3"
8)
9
10const (
11 rpl_statsping = "246"
12 rpl_localusers = "265"
13 rpl_globalusers = "266"
14 rpl_topicwhotime = "333"
15 err_invalidcapcmd = "410"
16)
17
18type modeSet string
19
20func (ms modeSet) Has(c byte) bool {
21 return strings.IndexByte(string(ms), c) >= 0
22}
23
24func (ms *modeSet) Add(c byte) {
25 if !ms.Has(c) {
26 *ms += modeSet(c)
27 }
28}
29
30func (ms *modeSet) Del(c byte) {
31 i := strings.IndexByte(string(*ms), c)
32 if i >= 0 {
33 *ms = (*ms)[:i] + (*ms)[i+1:]
34 }
35}
36
37func (ms *modeSet) Apply(s string) error {
38 var plusMinus byte
39 for i := 0; i < len(s); i++ {
40 switch c := s[i]; c {
41 case '+', '-':
42 plusMinus = c
43 default:
44 switch plusMinus {
45 case '+':
46 ms.Add(c)
47 case '-':
48 ms.Del(c)
49 default:
50 return fmt.Errorf("malformed modestring %q: missing plus/minus", s)
51 }
52 }
53 }
54 return nil
55}
56
57type channelStatus byte
58
59const (
60 channelPublic channelStatus = '='
61 channelSecret channelStatus = '@'
62 channelPrivate channelStatus = '*'
63)
64
65func parseChannelStatus(s string) (channelStatus, error) {
66 if len(s) > 1 {
67 return 0, fmt.Errorf("invalid channel status %q: more than one character", s)
68 }
69 switch cs := channelStatus(s[0]); cs {
70 case channelPublic, channelSecret, channelPrivate:
71 return cs, nil
72 default:
73 return 0, fmt.Errorf("invalid channel status %q: unknown status", s)
74 }
75}
76
77type membership byte
78
79const (
80 membershipFounder membership = '~'
81 membershipProtected membership = '&'
82 membershipOperator membership = '@'
83 membershipHalfOp membership = '%'
84 membershipVoice membership = '+'
85)
86
87const stdMembershipPrefixes = "~&@%+"
88
89func (m membership) String() string {
90 if m == 0 {
91 return ""
92 }
93 return string(m)
94}
95
96func parseMembershipPrefix(s string) (prefix membership, nick string) {
97 // TODO: any prefix from PREFIX RPL_ISUPPORT
98 if strings.IndexByte(stdMembershipPrefixes, s[0]) >= 0 {
99 return membership(s[0]), s[1:]
100 } else {
101 return 0, s
102 }
103}
104
105func parseMessageParams(msg *irc.Message, out ...*string) error {
106 if len(msg.Params) < len(out) {
107 return newNeedMoreParamsError(msg.Command)
108 }
109 for i := range out {
110 if out[i] != nil {
111 *out[i] = msg.Params[i]
112 }
113 }
114 return nil
115}
Note: See TracBrowser for help on using the repository browser.