Coverage report: /home/ellis/comp/core/lib/obj/secret.lisp

KindCoveredAll%
expression048 0.0
branch02 0.0
Key
Not instrumented
Conditionalized out
Executed
Not executed
 
Both branches taken
One branch taken
Neither branch taken
1
 ;;; secret.lisp --- Secret (concealed) Objects
2
 
3
 ;; Object wrapper intended to prevent leaking of sensitive data.
4
 
5
 ;;; Commentary:
6
 
7
 ;; ref: https://github.com/rotatef/secret-values
8
 
9
 ;;; Code:
10
 (in-package :obj/secret)
11
 
12
 (defclass secret ()
13
   ((name :initform (symbol-name #1=(gensym "secret")) :type string :accessor secret-name :initarg :name)
14
    (symbol :initform #1# :type symbol :accessor secret-symbol :initarg :symbol))
15
   (:documentation "A 'secret' object which is hidden from view when printing to avoid embarassing
16
 leakage of sensitive data."))
17
 
18
 (defmethod print-object ((self secret) stream)
19
   (if (secret-name self)
20
       (print-unreadable-object (self stream :type t :identity t)
21
         (princ (secret-name self) stream))
22
       (print-unreadable-object (self stream :type t :identity t))))
23
 
24
 (defgeneric conceal (self &key name class &allow-other-keys)
25
   (:documentation"Conceals value into a SECRET object. An optional name can be
26
 provided to aid debugging.")
27
   (:method ((self t) &key name (class 'secret))
28
     (let ((secret (apply #'make-instance class `(,@(when name `(:name ,name))
29
                                                    ,@(when name `(:symbol ,(make-symbol name)))))))
30
       (setf (get (secret-symbol secret) class) (lambda () self))
31
       secret)))
32
 
33
 (defgeneric reveal (self)
34
   (:documentation "Returns the secret value of SELF.")
35
   (:method ((self secret))
36
     (funcall (get (secret-symbol self) 'secret))))
37
 
38
 (defgeneric ensure-concealed (object &key name &allow-other-keys)
39
   (:documentation "If object is already a of type SECRET-VALUE returns is unaltered,
40
   otherwise conceals it as if by calling CONCEAL-VALUE.")
41
   (:method ((self t) &key name)
42
     (typecase self
43
       (secret self)
44
       (t (conceal self :name name)))))
45
 
46
 (defgeneric ensure-revealed (object)
47
   (:documentation "If object is type SECRET-VALUE returns the concealed value, otherwise returns object.")
48
   (:method ((self t))
49
     (typecase self
50
     (secret (reveal self))
51
     (t self))))