* smtp.el (smtp-check-response): Rewrite.
[elisp/flim.git] / net-trans.el
1 ;;; net-trans.el --- basic transaction framework for internet protocols
2
3 ;; Copyright (C) 2000 Daiki Ueno
4
5 ;; Author: Daiki Ueno <ueno@unixuser.org>
6 ;; Created: 2000/08/14
7
8 ;; This file is part of FLIM (Faithful Library about Internet Message).
9
10 ;; This program is free software; you can redistribute it and/or
11 ;; modify it under the terms of the GNU General Public License as
12 ;; published by the Free Software Foundation; either version 2, or (at
13 ;; your option) any later version.
14
15 ;; This program is distributed in the hope that it will be useful, but
16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 ;; General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with this program; see the file COPYING.  If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25
26 ;;; Commentary:
27 ;; 
28
29 ;;; Code:
30
31 (require 'luna)
32
33 (eval-when-compile (require 'cl))
34
35 (eval-and-compile
36   (luna-define-class net-transaction ())
37
38   (luna-define-internal-accessors 'net-transaction))
39
40 (luna-define-generic net-transaction-error-name (trans)
41   "Return error symbol of the TRANSACTION.")
42
43 (luna-define-generic net-transaction-error (trans error)
44   "Throw an ERROR of the TRANSACTION.")
45
46 (luna-define-method net-transaction-error-name ((trans net-transaction))
47   (intern (format "%s-error" (luna-class-name trans))))
48
49 (luna-define-method net-transaction-error ((trans net-transaction) error)
50   (throw (net-transaction-error-name trans) error))
51
52 (defvar net-transaction-combinator-alist
53   '((&& net-transaction-compose-&&)
54     (|| net-transaction-compose-||)))
55
56 (defun net-transaction-compose-&& (left right)
57   "Multiplicative combinator which composes LEFT and RIGHT operations."
58   `(lambda (trans)
59      (let ((next (funcall #',left trans)))
60        (funcall #',right next))))
61
62 (defun net-transaction-compose-|| (left right)
63   "Additive combinator which composes LEFT and RIGHT operations."
64   `(lambda (trans)
65      (let (next error)
66        (setq error
67              (catch (net-transaction-error-name trans)
68                (setq next (funcall #',left trans))
69                nil))
70        (if error
71            (funcall #',right trans)
72          next))))
73
74 (defun net-transaction-fold-left (function accu sequence)
75   "Apply FUNCTION to ACCU while folding SEQUENCE left to right."
76   (if (null sequence)
77       accu
78     (net-transaction-fold-left
79      function (funcall function accu (car sequence))
80      (cdr sequence))))
81
82 (defun net-transaction-compose-commands (commands)
83   "Compose transaction-function from COMMANDS."
84   (let ((combinator
85          (assq (pop commands) net-transaction-combinator-alist))
86         (accu
87          (if (listp (car commands))
88              (net-transaction-compose-commands (pop commands))
89            (pop commands))))
90     (if (null combinator)
91         (error "Unknown operator")
92       (setq accu
93             (net-transaction-fold-left
94              `(lambda (accu c)
95                 (funcall
96                  #',(nth 1 combinator) accu
97                  (if (listp c)
98                      (net-transaction-compose-commands c)
99                    c)))
100              accu commands))
101       (if (and (listp accu) (eq (car accu) 'lambda))
102           (byte-compile accu)
103         accu))))
104
105 (provide 'net-trans)
106
107 ;;; net-trans.el ends here