* net-trans.el: New file.
[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 transaction ())
37
38   (luna-define-internal-accessors 'transaction))
39
40 (luna-define-generic transaction-error-name (trans)
41   "Return error symbol of the TRANSACTION.")
42
43 (luna-define-method transaction-error-name ((trans transaction))
44   (intern (format "%s-error" (luna-class-name trans))))
45
46 (defvar transaction-combinator-alist
47   '((&& transaction-compose-&&)
48     (|| transaction-compose-||)))
49
50 (defun transaction-compose-&& (left right)
51   "Multiplicative operator of current transaction LEFT and RIGHT."
52   `(lambda (transaction)
53      (let ((next (funcall #',left transaction)))
54        (funcall #',right next))))
55
56 (defun transaction-compose-|| (left right)
57   "Additive operator of current transaction LEFT and RIGHT."
58   `(lambda (transaction)
59      (let (next error)
60        (setq error
61              (catch (transaction-error-name transaction)
62                (setq next (funcall #',left transaction))
63                nil))
64        (if error
65            (funcall #',right transaction)
66          next))))
67
68 (defun transaction-compose-fold-left (function accu sequence)
69   (if (null sequence)
70       accu
71     (transaction-compose-fold-left
72      function (funcall function accu (car sequence))
73      (cdr sequence))))
74
75 (defun transaction-compose-commands (commands)
76   "Compose COMMANDS."
77   (let ((combinator
78          (assq (pop commands) transaction-combinator-alist))
79         (accu
80          (if (listp (car commands))
81              (transaction-compose-commands (pop commands))
82            (pop commands))))
83     (if (null combinator)
84         (error "Unknown operator")
85       (setq accu
86             (transaction-compose-fold-left
87              `(lambda (accu c)
88                 (funcall
89                  #',(nth 1 combinator) accu
90                  (if (listp c)
91                      (transaction-compose-commands c)
92                    c)))
93              accu commands))
94       (if (byte-code-function-p accu)
95           accu
96         (byte-compile accu)))))
97
98 (provide 'net-trans)
99
100 ;;; net-trans.el ends here