# frozen_string_literal: true # typed: true require 'pp' module T::Props::PrettyPrintable include T::Props::Plugin # Override the PP gem with something that's similar, but gives us a hook to do redaction and customization def pretty_print(pp) klass = T.unsafe(T.cast(self, Object).class).decorator multiline = pp.is_a?(PP) pp.group(1, "<#{klass.inspect_class_with_decoration(self)}", ">") do klass.all_props.sort.each do |prop| pp.breakable val = klass.get(self, prop) rules = klass.prop_rules(prop) pp.text("#{prop}=") if (custom_inspect = rules[:inspect]) inspected = if T::Utils.arity(custom_inspect) == 1 custom_inspect.call(val) else custom_inspect.call(val, {multiline: multiline}) end pp.text(inspected.nil? ? "nil" : inspected) elsif rules[:sensitivity] && !rules[:sensitivity].empty? && !val.nil? pp.text("") else val.pretty_print(pp) end end klass.pretty_print_extra(self, pp) end end # Return a string representation of this object and all of its props in a single line def inspect string = +"" PP.singleline_pp(self, string) string end # Return a pretty string representation of this object and all of its props def pretty_inspect string = +"" PP.pp(self, string) string end module DecoratorMethods extend T::Sig sig {params(key: Symbol).returns(T::Boolean).checked(:never)} def valid_rule_key?(key) super || key == :inspect end # Overridable method to specify how the first part of a `pretty_print`d object's class should look like # NOTE: This is just to support Stripe's `PrettyPrintableModel` case, and not recommended to be overridden sig {params(instance: T::Props::PrettyPrintable).returns(String)} def inspect_class_with_decoration(instance) T.unsafe(instance).class.to_s end # Overridable method to add anything that is not a prop # NOTE: This is to support cases like Serializable's `@_extra_props`, and Stripe's `PrettyPrintableModel#@_deleted` sig {params(instance: T::Props::PrettyPrintable, pp: T.any(PrettyPrint, PP::SingleLine)).void} def pretty_print_extra(instance, pp); end end end