What is the best way to check if a value is of a specific class, for example java.io.file? Do I need to use :fn, like [:fn (partial instance? java.io.File)]
Yep, currently :fn is the way. See also:
https://github.com/metosin/malli/issues/1007
Thanks! Would be nice if direct support for classes was implemented
I think #(instance java.io.File %) is faster than (partial instance? java.io.File). The compiler emits more efficient bytecode. This is also tricky to work around for a general :instance schema. We'd want to precompile predicates for a statically-know set of classes in advance using macros for maximum performance.
Idea: provide a constructor for the :instance IntoSchema that takes options to configure how strictly you want to manage performance. Then you can decide when you add it to your registry. Tho I guess it'll be in the default registry, maybe it could be configured globally with jvm properties, not my favorite.
Well, we could take advantage of the fact that on JVM the compiler exists and simply eval an efficient predicate.
I made some pretty good progress on a schema for classes! https://github.com/frenchy64/malli/pull/41 For generators, it uses reflection to list constructors of the class and automatically calls them.
(deftest instance-schema-test
#?(:clj
(do (is (m/validate [:instance java.io.File] (java.io.File. "a")))
(let [s (m/schema [:instance java.io.File])]
(is (= {:schema s,
:value "a",
:errors [{:path [0], :in [], :schema s, :value "a"}]}
(m/explain s "a")))))))
(deftest instance-generator-test
#(:clj (is (= (mapv java.io.File/.getName (mg/sample [:instance java.io.File] {:seed 0}))
["" "6" "" "0" "" "Sb" "Bfv33" "hLM4T" "2j3Yk3" "jHYY5y3"]))))