Add schema_id(), handles different types with the same name #247
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #62 by implementing #62 (comment)
Schemars currently differentiates between types using the
JsonSchema::schema_name()
function, which typically returns the type name (excluding the module path). This PR updates the schema generator to differentiate between types using the new functionJsonSchema::schema_id()
, which is similar, but includes the type's module path. This leavesschema_name()
returning a clean, human-readable "friendly" name mostly free of rust details (e.g. being unaffected by module renames).schema_id()
has a default implementation (which delegates toschema_name()
), so this should be a non-breaking change.Because a vast majority of types have a statically-determined id (and name),
schema_id()
returns aCow<'static, str>
instead of aString
- in future, I'd like to changeschema_name()
to return aCow
for the same reason, but that will be a breaking change so is not being done in this PR. The main reason an implementation would return aCow::Owned(String)
would be a generic type, e.g.Vec<T>
, where the return value ofschema_id()
(and ofschema_name()
) depends on that ofT
.In many cases, the return value of
T::schema_id()
will be identical to that ofstd::any::type_name::<T>()
, so ideally we could just use that - unfortunatelytype_name()
is unsuitable here for two reasons:type_name()
may change in a future rust version e.g. by excluding the module path, or including lifetime specifiersschema_id()
, e.g.String
/str
/&str
, but these will all have different return values oftype_name()
Still to do:
schema_id()
✅schema_id()
appropriately for optional dependencies ✅