Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: extend-protocol IntoSchema for java.lang.Class and protocols #961

Closed
jasonjckn opened this issue Sep 24, 2023 · 5 comments
Closed

Comments

@jasonjckn
Copy link
Contributor

jasonjckn commented Sep 24, 2023

It would be nice if I could write code like

(m/validate [:maybe datomic.db.Db] my-db) ;; => true 

(or likewise for protocols.)

and it would just work out of the box .

If someone can confirm this is an acceptable feature, i'll write a PR.


e.g. ............ (work in progress) any early feedback?

(extend-protocol m/IntoSchema
  java.lang.Class
  (-type [^Class this] (symbol (.getName this)))
  (-type-properties [this])
  (-properties-schema [this options])
  (-children-schema [this options])
  (-into-schema [^Class this properties children options]
    (m/schema
      [:fn (merge {:error/message (str "should be an instance of java " this)} properties)
       #(clojure.core/instance? this %)]
      options)))

(m/validate String "foo") ;;=>  true 

protocols might be more challenging TBD.

@jasonjckn jasonjckn changed the title Feature: Implement IntoSchema for java.lang.Class and protocols Feature: extend-protocol IntoSchema for java.lang.Class and protocols Sep 24, 2023
@ikitommi
Copy link
Member

You can already add Class -> Schema via registry:

(m/validate [:tuple String Long]
            ["123" 123]
            {:registry (merge (m/default-schemas)
                              {String (m/-string-schema)
                               Long (m/-int-schema)})})
; => true

@ikitommi
Copy link
Member

... supporting classes out of the box would be nice, but not sure then there would be at least 3 ways to describe a string:

  • string? -> spec-like predicates
  • :string -> malli schema
  • String -> java Class

not sure if this makes the library easier to use.

@ikitommi
Copy link
Member

... maybe there should be a :instance schema? e.g.

(m/validate [:maybe [:instance datomic.db.Db]] my-db) ;; => true 

@jasonjckn
Copy link
Contributor Author

jasonjckn commented Sep 25, 2023

When I started down this path, i was hoping to handle ALL classes, interfaces & protocols out-of-the-box e.g.

(extend-protocol m/IntoSchema
  java.lang.Class
  .... instance? ....
  clojure.imaginary.Protocol
  ..... satisfies? .......

But protocols don't have their own Class to dispatch off of, rather are persistent data structures, and

(extend-protocol m/IntoSchema
    clojure.lang.PersistentArrayMap

Seems a bit janky, given all that, so i'm a lot less enthusiastic my original idea

Also, to your point about the performance of satisfies? , folks may want fine grained control e.g. [:maybe [:instance MyProtocol]], [:maybe [:satisfies MyProtocol]],

I can send a PR for that if you'd like... but since this is so close to [:fn #(satisfies? P %)] maybe it doesn't warrant its own abstraction... am split 50/50 on this too, maybe it's just better to keep malli API leen.


"You can already add Class -> Schema via registry"
sure, but I still need something like :instance .

(m/validate [:tuple String Long]
            ["123" 123]
            {:registry (merge (m/default-schemas)
                              {datomic.db.Db [:maybe [:instance datomic.db.Db]]})})

@jasonjckn
Copy link
Contributor Author

jasonjckn commented Sep 26, 2023

going to close this, while i'm going to commit this code to my own codebase, i don't feel like it's worthy of malli codebase yet... still needs hammock time for supporting all of classes, interfaces, protocols, etc — not just classes.

Please see #960 though, i'm still interested in the capability of -being able to do this-.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants