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

Expanding philosophy to moduledoc #41

Open
NoBrainSkull opened this issue May 26, 2023 · 2 comments
Open

Expanding philosophy to moduledoc #41

NoBrainSkull opened this issue May 26, 2023 · 2 comments

Comments

@NoBrainSkull
Copy link

Hello,

I'd love to expand this module philosophy to the documentation of the schema. Would you consider adding an option to the DSL to specify details about each field ?

Maybe something like :

defmodule Person do
  use TypedEctoSchema

  typed_schema "people", """
    Record of a customer.

   [...] Some other details about the schema.
    """ do
    field(:name, :string, enforce: true, null: false, doc: "fullname of the user")
    field(:age, :integer) :: non_neg_integer() | nil
    field(:happy, :boolean, default: true, null: false, doc: "satisfaction threshold computed from order satisfaction")
    field(:phone, :string, doc: "phone number obtained at first-order time")
    belongs_to(:company, Company)
    timestamps(type: :naive_datetime_usec)
  end
end

This would generate somehing like :

defmodule Person do
 @moduledoc """
    Record of a customer.

   [...] Some other details about the schema.

   ### Fields
   name: string - fullname of the user
   age: non_neg_integer - age
   happy: boolean - satisfaction threshold computed from order satisfaction
   phone: string - phone number obtained at first-order time
  """
  use Ecto.Schema

  @enforce_keys [:name]

  schema "people" do
    field(:name, :string)
    field(:age, :integer)
    field(:happy, :boolean, default: true)
    field(:phone, :string)
    belongs_to(:company, Company)
    timestamps(type: :naive_datetime_usec)
  end

  @type t() :: %__MODULE__{
          __meta__: Ecto.Schema.Metadata.t(),
          id: integer() | nil,
          name: String.t(),
          age: non_neg_integer() | nil,
          happy: boolean(),
          phone: String.t() | nil,
          company_id: integer() | nil,
          company: Company.t() | Ecto.Association.NotLoaded.t() | nil,
          inserted_at: NaiveDateTime.t(),
          updated_at: NaiveDateTime.t()
        }
end

As you know, we can very much define module attributes in macros. I'd be glad to do a pull request if you are open to the idea :)

Thanks

@bamorim
Copy link
Owner

bamorim commented May 29, 2023

@NoBrainSkull Although I like the idea of generating doc as well, this would go beyond the original proposal of the library and I'm not sure it would be something everyone would llke so I need to put more thought into that. Maybe that would be acceptable as an opt-in? Maybe if people specify the third argument as a string then it might make sense. Or maybe we could have something like

@schemadoc """
...
"""

That would automatically generate the @moduledoc like you described. I'm not sure how would be a good way of doing or if we should do it at all, however, I do like the idea. I think adding the ### Fields with the metadata we are already extracting can be a really good thing, so there is value to the idea.

Will have to think more about it. Thanks for the idea!
Proposal PRs are welcome, but maybe we should discuss a little bit more before jumping into implementation.

@NoBrainSkull
Copy link
Author

NoBrainSkull commented May 29, 2023

@bamorim thank you for considering the idea. To provide more fuel to it :

  • Something totally optional is the most appropriate approach (transparent for regular users)
  • Thinking about the module documentation, I played a bit with some code : I found out that we can get the value of a regular @moduledoc and simply append our generated field's documentation to it (this is done only if at least one field is documented). This avoid adding extra args to the main macros definitions (which is less cumbersome)
  • My team use-case is that we need to store some low-level fields (bitstrings and such). Usage documentation has a lot of value here.

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