Files
@ fd6bd1140427
Branch filter:
Location: workgroups2/src/workgroups-pickel.el - annotation
fd6bd1140427
11.1 KiB
text/x-elisp
Removed rest of filtration
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | 443938b472d4 5a6c3a89c877 443938b472d4 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 443938b472d4 8f748acf8fd3 5a6c3a89c877 443938b472d4 443938b472d4 443938b472d4 295f3038db4d 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 a8348263706b a8348263706b a8348263706b a8348263706b a8348263706b a8348263706b a8348263706b a8348263706b 5a6c3a89c877 a8348263706b a8348263706b a8348263706b a8348263706b a8348263706b 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 a8348263706b 5a6c3a89c877 5a6c3a89c877 a8348263706b 5a6c3a89c877 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 a8348263706b 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 443938b472d4 443938b472d4 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 295f3038db4d 443938b472d4 443938b472d4 443938b472d4 443938b472d4 295f3038db4d 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 e7e4d47f954c 443938b472d4 443938b472d4 295f3038db4d 295f3038db4d 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 5a6c3a89c877 443938b472d4 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 443938b472d4 a8348263706b 5a6c3a89c877 5a6c3a89c877 4a7bb1fd852b a8348263706b a8348263706b a8348263706b 5a6c3a89c877 5a6c3a89c877 4a7bb1fd852b 443938b472d4 443938b472d4 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 443938b472d4 443938b472d4 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 443938b472d4 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 443938b472d4 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 443938b472d4 443938b472d4 443938b472d4 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 443938b472d4 443938b472d4 443938b472d4 443938b472d4 a8348263706b 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 5a6c3a89c877 67d47ad4e0bd 5a6c3a89c877 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 443938b472d4 088605c05794 | ;;; workgroups-pickel.el --- Elisp object serdes used by Workgroups
;;; Commentary:
;;
;; Workgroups allows you to serialize some objects, even such as buffers
;; (that are displayed as #<object>). The only trick is to write
;; functions that extract enough information about an object and
;; functions that can recreate an object.
;;
;; Main functions are: `wg-pickel', `wg-pickel-to-string',
;; What objects are supported? See `wg-pickel-pickelable-types'
;;
;;; Code:
(require 'cl-lib)
(require 'workgroups-utils-basic)
(defvar wg-pickel-identifier '~pickel!~
"Symbol identifying a stream as a pickel.")
(defvar wg-pickel-pickelable-types
'(integer
float
symbol
string
cons
vector
hash-table
buffer
marker
;;window-configuration
;;frame
;;window
;;process
)
"Types pickel can serialize.")
(defvar wg-pickel-object-serializers
'((integer . identity)
(float . identity)
(string . identity)
(symbol . wg-pickel-symbol-serializer)
(cons . wg-pickel-cons-serializer)
(vector . wg-pickel-vector-serializer)
(hash-table . wg-pickel-hash-table-serializer)
(buffer . wg-pickel-buffer-serializer)
(marker . wg-pickel-marker-serializer)
;;(window-configuration . wg-pickel-window-configuration-serializer)
)
"Alist mapping types to object serialization functions.")
(defvar wg-pickel-object-deserializers
'((s . wg-pickel-deserialize-uninterned-symbol)
(c . wg-pickel-deserialize-cons)
(v . wg-pickel-deserialize-vector)
(h . wg-pickel-deserialize-hash-table)
(b . wg-pickel-deserialize-buffer)
(m . wg-pickel-deserialize-marker)
;;(f . wg-pickel-deserialize-frame)
)
"Alist mapping type keys to object deserialization functions.")
(defvar wg-pickel-link-serializers
'((cons . wg-pickel-cons-link-serializer)
(vector . wg-pickel-vector-link-serializer)
(hash-table . wg-pickel-hash-table-link-serializer))
"Alist mapping types to link serialization functions.")
(defvar wg-pickel-link-deserializers
`((c . wg-pickel-cons-link-deserializer)
(v . wg-pickel-vector-link-deserializer)
(h . wg-pickel-hash-table-link-deserializer))
"Alist mapping type keys to link deserialization functions.")
;;; errors and predicates
(put 'wg-pickel-unpickelable-type-error
'error-conditions
'(error wg-pickel-errors wg-pickel-unpickelable-type-error))
(put 'wg-pickel-unpickelable-type-error
'error-message
"Attemp to pickel unpickelable type")
(defun wg-pickelable-or-error (obj)
"Error when OBJ isn't pickelable."
(unless (memq (type-of obj) wg-pickel-pickelable-types)
(signal 'wg-pickel-unpickelable-type-error
(format "Can't pickel objects of type: %S" (type-of obj))))
(cl-typecase obj
(cons
(wg-pickelable-or-error (car obj))
(wg-pickelable-or-error (cdr obj)))
(vector
(cl-map nil 'wg-pickelable-or-error obj))
(hash-table
(wg-dohash (key value obj)
(wg-pickelable-or-error key)
(wg-pickelable-or-error value)))))
(defun wg-pickelable-p (obj)
(condition-case err
(progn (wg-pickelable-or-error obj) t)
(wg-pickel-unpickelable-type-error nil)))
(defun wg-pickel-p (obj)
"Return t when OBJ is a pickel, nil otherwise."
(and (consp obj) (eq (car obj) wg-pickel-identifier)))
;; accessor functions
(defun wg-pickel-object-serializer (obj)
"Return the object serializer for the `type-of' OBJ."
(or (wg-aget wg-pickel-object-serializers (type-of obj))
(error "Invalid type: %S" (type-of obj))))
(defun wg-pickel-link-serializer (obj)
"Return the link serializer for the `type-of' OBJ."
(wg-aget wg-pickel-link-serializers (type-of obj)))
(defun wg-pickel-object-deserializer (key)
"Return the object deserializer for type key KEY, or error."
(or (wg-aget wg-pickel-object-deserializers key)
(error "Invalid object deserializer key: %S" key)))
(defun wg-pickel-link-deserializer (key)
"Return the link deserializer for type key KEY, or error."
(or (wg-aget wg-pickel-link-deserializers key)
(error "Invalid link deserializer key: %S" key)))
;;; bindings
(defun wg-pickel-make-bindings-table (obj)
"Return a table binding unique subobjects of OBJ to ids."
(let ((binds (make-hash-table :test 'eq))
(id -1))
(cl-labels
((inner (obj)
(unless (gethash obj binds)
(puthash obj (cl-incf id) binds)
(cl-case (type-of obj)
(cons
(inner (car obj))
(inner (cdr obj)))
(vector
(dotimes (idx (length obj))
(inner (aref obj idx))))
(hash-table
(wg-dohash (key val obj)
(inner key)
(inner val)))))))
(inner obj)
binds)))
;;; Objects
;; symbol
;; (wg-unpickel (wg-pickel 123))
;; (wg-unpickel (wg-pickel "table"))
;; (wg-unpickel (wg-pickel 'test))
(defun wg-pickel-symbol-serializer (symbol)
"Return SYMBOL's serialization."
(cond ((eq symbol t) t)
((eq symbol nil) nil)
((intern-soft symbol) symbol)
(t (list 's (symbol-name symbol)))))
(defun wg-pickel-deserialize-uninterned-symbol (name)
"Return a new uninterned symbol from NAME."
(make-symbol name))
;; buffer
;; (wg-unpickel (wg-pickel (current-buffer)))
;; (wg-unpickel (wg-pickel (get-buffer org-agenda-buffer-name)))
(defun wg-pickel-buffer-serializer (buffer)
"Return BUFFER's UID in workgroups buffer list."
(list 'b (wg-add-buffer-to-buf-list buffer)))
(defun wg-pickel-deserialize-buffer (uid)
"Return a restored buffer from it's UID."
(wg-restore-buffer (wg-find-buf-by-uid uid)))
;; marker
;; (wg-unpickel (wg-pickel (point-marker)))
(defun wg-pickel-marker-serializer (marker)
"Return MARKERS's data."
(list 'm (list (marker-position marker)
(wg-add-buffer-to-buf-list (marker-buffer marker)))))
(defun wg-pickel-deserialize-marker (data)
"Return marker from it's data."
(let ((m (make-marker)))
(set-marker m (car data) (wg-pickel-deserialize-buffer (car (cdr data))))))
;; cons - http://www.gnu.org/software/emacs/manual/html_node/eintr/cons.html
(defun wg-pickel-cons-serializer (cons)
"Return CONS's serialization."
(list 'c))
(defun wg-pickel-deserialize-cons ()
"Return a new cons cell initialized to nil."
(cons nil nil))
(defun wg-pickel-cons-link-serializer (cons binds)
"Return the serialization of CONS's links in BINDS."
(list 'c
(gethash cons binds)
(gethash (car cons) binds)
(gethash (cdr cons) binds)))
(defun wg-pickel-cons-link-deserializer (cons-id car-id cdr-id binds)
"Relink a cons cell with its car and cdr in BINDS."
(let ((cons (gethash cons-id binds)))
(setcar cons (gethash car-id binds))
(setcdr cons (gethash cdr-id binds))))
;; vector - http://www.gnu.org/software/emacs/manual/html_node/elisp/Vector-Functions.html
;; (wg-unpickel (wg-pickel (make-vector 9 'Z)))
;;
(defun wg-pickel-vector-serializer (vector)
"Return VECTOR's serialization."
(list 'v (length vector)))
(defun wg-pickel-deserialize-vector (length)
"Return a new vector of length LENGTH."
(make-vector length nil))
(defun wg-pickel-vector-link-serializer (vector binds)
"Return the serialization of VECTOR's links in BINDS."
(let (result)
(dotimes (i (length vector) result)
(setq result
(nconc (list 'v
(gethash vector binds)
i
(gethash (aref vector i) binds))
result)))))
(defun wg-pickel-vector-link-deserializer (vector-id index value-id binds)
"Relink a vector with its elements in BINDS."
(aset (gethash vector-id binds) index (gethash value-id binds)))
;; hash table - http://www.gnu.org/software/emacs/manual/html_node/elisp/Hash-Tables.html
(defun wg-pickel-hash-table-serializer (table)
"Return HASH-TABLE's serialization."
(list 'h
(hash-table-test table)
(hash-table-size table)
(hash-table-rehash-size table)
(hash-table-rehash-threshold table)
(hash-table-weakness table)))
(defun wg-pickel-deserialize-hash-table (test size rsize rthresh weakness)
"Return a new hash-table with the specified properties."
(make-hash-table :test test :size size :rehash-size rsize
:rehash-threshold rthresh :weakness weakness))
(defun wg-pickel-hash-table-link-serializer (table binds)
"Return the serialization of TABLE's links in BINDS."
(let (result)
(wg-dohash (key value table result)
(setq result
(nconc (list 'h
(gethash key binds)
(gethash value binds)
(gethash table binds))
result)))))
(defun wg-pickel-hash-table-link-deserializer (key-id value-id table-id binds)
"Relink a hash-table with its keys and values in BINDS."
(puthash (gethash key-id binds)
(gethash value-id binds)
(gethash table-id binds)))
;; TODO
(defun wg-pickel-window-configuration-serializer (wc)
"Return Window configuration WC's serialization."
(list 'wc 1))
(defun wg-pickel-serialize-objects (binds)
"Return a list of serializations of the objects in BINDS."
(let (result)
(wg-dohash (obj id binds result)
(setq result
(nconc (list id (funcall (wg-pickel-object-serializer obj) obj))
result)))))
(defun wg-pickel-deserialize-objects (serial-objects)
"Return a hash-table of objects deserialized from SERIAL-OBJECTS."
(let ((binds (make-hash-table)))
(wg-destructuring-dolist ((id obj . rest) serial-objects binds)
(puthash id
(if (atom obj) obj
(wg-dbind (key . data) obj
(apply (wg-pickel-object-deserializer key) data)))
binds))))
(defun wg-pickel-serialize-links (binds)
"Return a list of serializations of the links between objects in BINDS."
(let (result)
(wg-dohash (obj id binds result)
(awhen (wg-pickel-link-serializer obj)
(setq result (nconc (funcall it obj binds) result))))))
(defun wg-pickel-deserialize-links (serial-links binds)
"Return BINDS after relinking all its objects according to SERIAL-LINKS."
(wg-destructuring-dolist ((key arg1 arg2 arg3 . rest) serial-links binds)
(funcall (wg-pickel-link-deserializer key) arg1 arg2 arg3 binds)))
;;; pickeling
(defun wg-pickel (obj)
"Return the serialization of OBJ."
(wg-pickelable-or-error obj)
(let ((binds (wg-pickel-make-bindings-table obj)))
(list wg-pickel-identifier
(wg-pickel-serialize-objects binds)
(wg-pickel-serialize-links binds)
(gethash obj binds))))
(defun wg-pickel-to-string (obj)
"Serialize OBJ to a string and return the string."
(format "%S" (wg-pickel obj)))
(defun wg-unpickel (pickel)
"Return the deserialization of PICKEL."
(unless (wg-pickel-p pickel)
(error "Attempt to unpickel a non-pickel."))
(wg-dbind (id serial-objects serial-links result) pickel
(gethash
result
(wg-pickel-deserialize-links
serial-links
(wg-pickel-deserialize-objects serial-objects)))))
(provide 'workgroups-pickel)
;;; workgroups-pickel.el ends here
|