Re: Xapers
[notmuch-archives.git] / 85 / 223f70d2eecaaf6bd289fca50710dffe4df12b
1 Return-Path: <amdragon@mit.edu>\r
2 X-Original-To: notmuch@notmuchmail.org\r
3 Delivered-To: notmuch@notmuchmail.org\r
4 Received: from localhost (localhost [127.0.0.1])\r
5         by olra.theworths.org (Postfix) with ESMTP id CD78A431FAF\r
6         for <notmuch@notmuchmail.org>; Wed, 18 Jul 2012 13:50:32 -0700 (PDT)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: -0.7\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5\r
12         tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
13 Received: from olra.theworths.org ([127.0.0.1])\r
14         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
15         with ESMTP id YylisYt207DJ for <notmuch@notmuchmail.org>;\r
16         Wed, 18 Jul 2012 13:50:31 -0700 (PDT)\r
17 Received: from dmz-mailsec-scanner-8.mit.edu (DMZ-MAILSEC-SCANNER-8.MIT.EDU\r
18         [18.7.68.37])\r
19         by olra.theworths.org (Postfix) with ESMTP id 9BB9E431FAE\r
20         for <notmuch@notmuchmail.org>; Wed, 18 Jul 2012 13:50:31 -0700 (PDT)\r
21 X-AuditID: 12074425-b7f9b6d0000008c4-55-500721978e0e\r
22 Received: from mailhub-auth-3.mit.edu ( [18.9.21.43])\r
23         by dmz-mailsec-scanner-8.mit.edu (Symantec Messaging Gateway) with SMTP\r
24         id 80.47.02244.79127005; Wed, 18 Jul 2012 16:50:31 -0400 (EDT)\r
25 Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103])\r
26         by mailhub-auth-3.mit.edu (8.13.8/8.9.2) with ESMTP id q6IKoUbe025232; \r
27         Wed, 18 Jul 2012 16:50:30 -0400\r
28 Received: from awakening.csail.mit.edu (awakening.csail.mit.edu [18.26.4.91])\r
29         (authenticated bits=0)\r
30         (User authenticated as amdragon@ATHENA.MIT.EDU)\r
31         by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id q6IKoTwC007340\r
32         (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT);\r
33         Wed, 18 Jul 2012 16:50:30 -0400 (EDT)\r
34 Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.77)\r
35         (envelope-from <amdragon@mit.edu>)\r
36         id 1SrbCX-0001EO-1E; Wed, 18 Jul 2012 16:50:29 -0400\r
37 Date: Wed, 18 Jul 2012 16:50:28 -0400\r
38 From: Austin Clements <amdragon@MIT.EDU>\r
39 To: Adrien Bustany <adrien@bustany.org>\r
40 Subject: Re: [PATCH 7/7] go: Bind notmuch_thread_t functions\r
41 Message-ID: <20120718205028.GV31670@mit.edu>\r
42 References: <1342636475-16057-1-git-send-email-adrien@bustany.org>\r
43         <1342636475-16057-8-git-send-email-adrien@bustany.org>\r
44 MIME-Version: 1.0\r
45 Content-Type: text/plain; charset=us-ascii\r
46 Content-Disposition: inline\r
47 In-Reply-To: <1342636475-16057-8-git-send-email-adrien@bustany.org>\r
48 User-Agent: Mutt/1.5.21 (2010-09-15)\r
49 X-Brightmail-Tracker:\r
50  H4sIAAAAAAAAA+NgFmpmleLIzCtJLcpLzFFi42IR4hTV1p2uyB5gsOcSj8X6O2vZLK7fnMns\r
51         wOTx8cA9Jo9nq24xBzBFcdmkpOZklqUW6dslcGUseBFbcM+3ouPnTKYGxt/WXYycHBICJhIb\r
52         d/5mhrDFJC7cW8/WxcjFISSwj1Hi+bp1rBDOBkaJ1ee7WSCck0wSH5p7oJwljBLbH71gAeln\r
53         EVCVeH37KRuIzSagIbFt/3JGEFtEQF1iR2c7mM0sIC3x7XczE4gtLGAj8fHJBLB6XgEdiSez\r
54         ZrCD2EIC1RLfP6xggYgLSpyc+YQFoldL4sa/l0C9HGBzlv/jAAlzCjhLXP++gxXEFhVQkZhy\r
55         chvbBEahWUi6ZyHpnoXQvYCReRWjbEpulW5uYmZOcWqybnFyYl5eapGuhV5uZoleakrpJkZQ\r
56         WLO7qO5gnHBI6RCjAAejEg/vg12sAUKsiWXFlbmHGCU5mJREeT8JsQcI8SXlp1RmJBZnxBeV\r
57         5qQWH2KU4GBWEuF9IAiU401JrKxKLcqHSUlzsCiJ895IuekvJJCeWJKanZpakFoEk5Xh4FCS\r
58         4L2uANQoWJSanlqRlplTgpBm4uAEGc4DNJxbEWR4cUFibnFmOkT+FKOilDjvepBmAZBERmke\r
59         XC8s7bxiFAd6RZj3EkgVDzBlwXW/AhrMBDK4mA1kcEkiQkqqgbHueRjn28kB6u3F//mt1h1R\r
60         FFmk1nWgcw1T/aPCjhL3usqUg8K71BJkVN+WOLw4q8efv+CI6T7/q488/2zy5GbbtDDLv1sg\r
61         88/VB5NiSj/nrZkXbeFbdjDNQ+7Hye6fjMafDjy49Ckn9Gt7p5355sApT/evvGd0ovpGcu9W\r
62         HsEdEvxzCqbZr1ViKc5INNRiLipOBADBrsVfFgMAAA==\r
63 Cc: notmuch@notmuchmail.org\r
64 X-BeenThere: notmuch@notmuchmail.org\r
65 X-Mailman-Version: 2.1.13\r
66 Precedence: list\r
67 List-Id: "Use and development of the notmuch mail system."\r
68         <notmuch.notmuchmail.org>\r
69 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
70         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
71 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
72 List-Post: <mailto:notmuch@notmuchmail.org>\r
73 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
74 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
75         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
76 X-List-Received-Date: Wed, 18 Jul 2012 20:50:32 -0000\r
77 \r
78 Quoth Adrien Bustany on Jul 18 at  9:34 pm:\r
79 > ---\r
80 >  bindings/go/src/notmuch/notmuch.go |  253 +++++++++++++++++++++++++++++++++++-\r
81 >  1 files changed, 252 insertions(+), 1 deletions(-)\r
82\r
83 > diff --git a/bindings/go/src/notmuch/notmuch.go b/bindings/go/src/notmuch/notmuch.go\r
84 > index be4cb8c..f667dbb 100644\r
85 > --- a/bindings/go/src/notmuch/notmuch.go\r
86 > +++ b/bindings/go/src/notmuch/notmuch.go\r
87 > @@ -12,6 +12,8 @@ package notmuch\r
88 >  */\r
89 >  import "C"\r
90 >  import "runtime"\r
91 > +import "strings"\r
92 > +import "time"\r
93 >  import "unsafe"\r
94 >  \r
95 >  // Status codes used for the return values of most functions\r
96 > @@ -700,7 +702,20 @@ func (self *Query) CountMessages() uint {\r
97 >       return uint(C.notmuch_query_count_messages(self.query))\r
98 >  }\r
99 >  \r
100 > -// TODO: wrap threads and thread\r
101 > +/* Return the number of threads matching a search.\r
102 > + *\r
103 > + * This function performs a search and returns the number of unique thread IDs\r
104 > + * in the matching messages. This is the same as number of threads matching a\r
105 > + * search.\r
106 > + *\r
107 > + * Note that this is a significantly heavier operation than\r
108 > + * notmuch_query_count_messages().\r
109 > + *\r
110 > + * If an error occurs, this function may return 0.\r
111 > + */\r
112 > +func (self *Query) CountThreads() uint {\r
113 > +     return uint(C.notmuch_query_count_threads(self.query))\r
114 > +}\r
115 >  \r
116 >  /* Is the given 'threads' iterator pointing at a valid thread.\r
117 >   *\r
118 > @@ -722,6 +737,45 @@ func (self *Threads) Valid() bool {\r
119 >       return true\r
120 >  }\r
121 >  \r
122 > +/* Get the current thread from 'threads' as a notmuch_thread_t.\r
123 > + *\r
124 > + * Note: The returned thread belongs to 'threads' and has a lifetime\r
125 > + * identical to it (and the query to which it belongs).\r
126 > + *\r
127 > + * See the documentation of notmuch_query_search_threads for example\r
128 > + * code showing how to iterate over a notmuch_threads_t object.\r
129 > + *\r
130 > + * If an out-of-memory situation occurs, this function will return\r
131 > + * NULL.\r
132 > + */\r
133 > +func (self *Threads) Get() *Thread {\r
134 > +     if self.threads == nil {\r
135 > +             return nil\r
136 > +     }\r
137 > +     thread := C.notmuch_threads_get(self.threads)\r
138 > +     if thread == nil {\r
139 > +             return nil\r
140 > +     }\r
141 > +     return createThread(thread, self)\r
142 > +}\r
143 > +\r
144 > +/* Move the 'threads' iterator to the next thread.\r
145 > + *\r
146 > + * If 'threads' is already pointing at the last thread then the\r
147 > + * iterator will be moved to a point just beyond that last thread,\r
148 > + * (where notmuch_threads_valid will return FALSE and\r
149 > + * notmuch_threads_get will return NULL).\r
150 > + *\r
151 > + * See the documentation of notmuch_query_search_threads for example\r
152 > + * code showing how to iterate over a notmuch_threads_t object.\r
153 > + */\r
154 > +func (self *Threads) MoveToNext() {\r
155 > +     if self.threads == nil {\r
156 > +             return\r
157 > +     }\r
158 > +     C.notmuch_threads_move_to_next(self.threads)\r
159 > +}\r
160 > +\r
161 >  /* Destroy a notmuch_threads_t object.\r
162 >   *\r
163 >   * It's not strictly necessary to call this function. All memory from\r
164 > @@ -735,6 +789,203 @@ func (self *Threads) Destroy() {\r
165 >       }\r
166 >  }\r
167 >  \r
168 > +/* Get the thread ID of 'thread'.\r
169 > + *\r
170 > + * The returned string belongs to 'thread' and as such, should not be\r
171 > + * modified by the caller and will only be valid for as long as the\r
172 > + * thread is valid, (which is until notmuch_thread_destroy or until\r
173 > + * the query from which it derived is destroyed).\r
174 > + */\r
175 > +func (self *Thread) GetThreadId() string {\r
176 > +     if self.thread == nil {\r
177 > +             return ""\r
178 > +     }\r
179 > +     id := C.notmuch_thread_get_thread_id(self.thread)\r
180 > +\r
181 > +     if id == nil {\r
182 > +             return ""\r
183 > +     }\r
184 > +\r
185 > +     return C.GoString(id)\r
186 > +}\r
187 > +\r
188 > +/* Get the total number of messages in 'thread'.\r
189 > + *\r
190 > + * This count consists of all messages in the database belonging to\r
191 > + * this thread. Contrast with notmuch_thread_get_matched_messages() .\r
192 > + */\r
193 > +func (self *Thread) GetTotalMessages() int {\r
194 > +     if self.thread == nil {\r
195 > +             return 0\r
196 > +     }\r
197 > +     return int(C.notmuch_thread_get_total_messages(self.thread))\r
198 > +}\r
199 > +\r
200 > +/* Get a notmuch_messages_t iterator for the top-level messages in\r
201 > + * 'thread'.\r
202 > + *\r
203 > + * This iterator will not necessarily iterate over all of the messages\r
204 > + * in the thread. It will only iterate over the messages in the thread\r
205 > + * which are not replies to other messages in the thread.\r
206 > + *\r
207 > + * To iterate over all messages in the thread, the caller will need to\r
208 > + * iterate over the result of notmuch_message_get_replies for each\r
209 > + * top-level message (and do that recursively for the resulting\r
210 > + * messages, etc.).\r
211 > + */\r
212 > +func (self *Thread) GetToplevelMessages() *Messages {\r
213 > +     if self.thread == nil {\r
214 > +             return nil\r
215 > +     }\r
216 > +     msgs := C.notmuch_thread_get_toplevel_messages(self.thread)\r
217 > +     if msgs == nil {\r
218 > +             return nil\r
219 > +     }\r
220 > +     return createMessages(msgs, self)\r
221 > +}\r
222 > +\r
223 > +/* Get a notmuch_messages_t iterator for the top-level messages in\r
224 > + * 'thread'.\r
225 > + *\r
226 > + * This iterator will not necessarily iterate over all of the messages\r
227 > + * in the thread. It will only iterate over the messages in the thread\r
228 > + * which are not replies to other messages in the thread.\r
229 > + *\r
230 > + * To iterate over all messages in the thread, the caller will need to\r
231 > + * iterate over the result of notmuch_message_get_replies for each\r
232 > + * top-level message (and do that recursively for the resulting\r
233 > + * messages, etc.).\r
234 > + */\r
235 \r
236 Wrong comment.  (Same for the next two methods.)\r
237 \r
238 > +func (self *Thread) GetMatchedMessages() int {\r
239 > +     if self.thread == nil {\r
240 > +             return 0\r
241 > +     }\r
242 > +     return int(C.notmuch_thread_get_matched_messages(self.thread))\r
243 > +}\r
244 > +\r
245 > +/* Get a notmuch_messages_t iterator for the top-level messages in\r
246 > + * 'thread'.\r
247 > + *\r
248 > + * This iterator will not necessarily iterate over all of the messages\r
249 > + * in the thread. It will only iterate over the messages in the thread\r
250 > + * which are not replies to other messages in the thread.\r
251 > + *\r
252 > + * To iterate over all messages in the thread, the caller will need to\r
253 > + * iterate over the result of notmuch_message_get_replies for each\r
254 > + * top-level message (and do that recursively for the resulting\r
255 > + * messages, etc.).\r
256 > + */\r
257 > +func (self *Thread) GetAuthors() []string {\r
258 > +     if self.thread == nil {\r
259 > +             return make([]string, 0)\r
260 > +     }\r
261 > +     authors_str := C.notmuch_thread_get_authors(self.thread)\r
262 > +\r
263 > +     if authors_str == nil {\r
264 > +             return make([]string, 0)\r
265 > +     }\r
266 > +\r
267 > +     return strings.Split(C.GoString(authors_str), ", ")\r
268 > +}\r
269 > +\r
270 > +/* Get the subject of 'thread'\r
271 > + *\r
272 > + * The subject is taken from the first message (according to the query\r
273 > + * order---see notmuch_query_set_sort) in the query results that\r
274 > + * belongs to this thread.\r
275 > + *\r
276 > + * The returned string belongs to 'thread' and as such, should not be\r
277 > + * modified by the caller and will only be valid for as long as the\r
278 > + * thread is valid, (which is until notmuch_thread_destroy or until\r
279 > + * the query from which it derived is destroyed).\r
280 > + */\r
281 > +func (self *Thread) GetSubject() string {\r
282 > +     if self.thread == nil {\r
283 > +             return ""\r
284 > +     }\r
285 > +     subject := C.notmuch_thread_get_subject(self.thread)\r
286 > +\r
287 > +     if subject == nil {\r
288 > +             return ""\r
289 > +     }\r
290 > +\r
291 > +     return C.GoString(subject)\r
292 > +}\r
293 > +\r
294 > +/* Get the date of the oldest message in 'thread' as a time_t value.\r
295 > + */\r
296 > +func (self *Thread) GetOldestDate() time.Time {\r
297 > +     if self.thread == nil {\r
298 > +             return time.Unix(0, 0)\r
299 > +     }\r
300 > +     return time.Unix(int64(C.notmuch_thread_get_oldest_date(self.thread)), 0)\r
301 > +}\r
302 > +\r
303 > +/* Get the date of the newest message in 'thread' as a time_t value.\r
304 > + */\r
305 > +func (self *Thread) GetNewestDate() time.Time {\r
306 > +     if self.thread == nil {\r
307 > +             return time.Unix(0, 0)\r
308 > +     }\r
309 > +     return time.Unix(int64(C.notmuch_thread_get_oldest_date(self.thread)), 0)\r
310 > +}\r
311 > +\r
312 > +/* Get the tags for 'thread', returning a notmuch_tags_t object which\r
313 > + * can be used to iterate over all tags.\r
314 > + *\r
315 > + * Note: In the Notmuch database, tags are stored on individual\r
316 > + * messages, not on threads. So the tags returned here will be all\r
317 > + * tags of the messages which matched the search and which belong to\r
318 > + * this thread.\r
319 > + *\r
320 > + * The tags object is owned by the thread and as such, will only be\r
321 > + * valid for as long as the thread is valid, (for example, until\r
322 > + * notmuch_thread_destroy or until the query from which it derived is\r
323 > + * destroyed).\r
324 > + *\r
325 > + * Typical usage might be:\r
326 > + *\r
327 > + *     notmuch_thread_t *thread;\r
328 > + *     notmuch_tags_t *tags;\r
329 > + *     const char *tag;\r
330 > + *\r
331 > + *     thread = notmuch_threads_get (threads);\r
332 > + *\r
333 > + *     for (tags = notmuch_thread_get_tags (thread);\r
334 > + *          notmuch_tags_valid (tags);\r
335 > + *          notmuch_result_move_to_next (tags))\r
336 > + *     {\r
337 > + *         tag = notmuch_tags_get (tags);\r
338 > + *         ....\r
339 > + *     }\r
340 > + *\r
341 > + *     notmuch_thread_destroy (thread);\r
342 \r
343 I wonder if this example should be updated for Go?  OTOH, all of the\r
344 comments seem to be copied verbatim, to the point of referring to C\r
345 function names and status symbols.\r
346 \r
347 > + *\r
348 > + * Note that there's no explicit destructor needed for the\r
349 > + * notmuch_tags_t object. (For consistency, we do provide a\r
350 > + * notmuch_tags_destroy function, but there's no good reason to call\r
351 > + * it if the message is about to be destroyed).\r
352 > + */\r
353 > +func (self *Thread) GetTags() *Tags {\r
354 > +     if self.thread == nil {\r
355 > +             return nil\r
356 > +     }\r
357 > +     tags := C.notmuch_thread_get_tags(self.thread)\r
358 > +     if tags == nil {\r
359 > +             return nil\r
360 > +     }\r
361 > +     return createTags(tags, self)\r
362 > +}\r
363 > +\r
364 > +/* Destroy a notmuch_thread_t object. */\r
365 > +func (self *Thread) Destroy() {\r
366 > +     if self.thread == nil {\r
367 > +             return\r
368 > +     }\r
369 > +     C.notmuch_thread_destroy(self.thread)\r
370 > +     self.thread = nil\r
371 > +}\r
372 > +\r
373 >  /* Is the given 'messages' iterator pointing at a valid message.\r
374 >   *\r
375 >   * When this function returns TRUE, notmuch_messages_get will return a\r