1 // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! HTML formatting module
13 //! This module contains a large number of `fmt::Display` implementations for
14 //! various types in `rustdoc::clean`. These implementations all currently
15 //! assume that HTML output is desired, although it may be possible to redesign
16 //! them in the future to instead emit any format desired.
19 use std
::iter
::repeat
;
21 use rustc
::hir
::def_id
::DefId
;
22 use rustc_target
::spec
::abi
::Abi
;
25 use clean
::{self, PrimitiveType}
;
26 use core
::DocAccessLevels
;
27 use html
::item_type
::ItemType
;
28 use html
::render
::{self, cache, CURRENT_LOCATION_KEY}
;
30 /// Helper to render an optional visibility with a space after it (if the
31 /// visibility is preset)
32 #[derive(Copy, Clone)]
33 pub struct VisSpace
<'a
>(pub &'a Option
<clean
::Visibility
>);
34 /// Similarly to VisSpace, this structure is used to render a function style with a
36 #[derive(Copy, Clone)]
37 pub struct UnsafetySpace(pub hir
::Unsafety
);
38 /// Similarly to VisSpace, this structure is used to render a function constness
39 /// with a space after it.
40 #[derive(Copy, Clone)]
41 pub struct ConstnessSpace(pub hir
::Constness
);
42 /// Similar to VisSpace, but used for mutability
43 #[derive(Copy, Clone)]
44 pub struct MutableSpace(pub clean
::Mutability
);
45 /// Similar to VisSpace, but used for mutability
46 #[derive(Copy, Clone)]
47 pub struct RawMutableSpace(pub clean
::Mutability
);
48 /// Wrapper struct for emitting type parameter bounds.
49 pub struct TyParamBounds
<'a
>(pub &'a
[clean
::TyParamBound
]);
50 /// Wrapper struct for emitting a comma-separated list of items
51 pub struct CommaSep
<'a
, T
: 'a
>(pub &'a
[T
]);
52 pub struct AbiSpace(pub Abi
);
54 /// Wrapper struct for properly emitting a method declaration.
55 pub struct Method
<'a
> {
56 /// The declaration to emit.
57 pub decl
: &'a clean
::FnDecl
,
58 /// The length of the function's "name", used to determine line-wrapping.
60 /// The number of spaces to indent each successive line with, if line-wrapping is necessary.
64 /// Wrapper struct for emitting a where clause from Generics.
65 pub struct WhereClause
<'a
>{
66 /// The Generics from which to emit a where clause.
67 pub gens
: &'a clean
::Generics
,
68 /// The number of spaces to indent each line with.
70 /// Whether the where clause needs to add a comma and newline after the last bound.
71 pub end_newline
: bool
,
79 impl<'a
> VisSpace
<'a
> {
80 pub fn get(self) -> &'a Option
<clean
::Visibility
> {
81 let VisSpace(v
) = self; v
86 pub fn get(&self) -> hir
::Unsafety
{
87 let UnsafetySpace(v
) = *self; v
92 pub fn get(&self) -> hir
::Constness
{
93 let ConstnessSpace(v
) = *self; v
97 impl<'a
, T
: fmt
::Display
> fmt
::Display
for CommaSep
<'a
, T
> {
98 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
99 for (i
, item
) in self.0.iter
().enumerate() {
100 if i
!= 0 { write!(f, ", ")?; }
101 fmt
::Display
::fmt(item
, f
)?
;
107 impl<'a
> fmt
::Display
for TyParamBounds
<'a
> {
108 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
109 let &TyParamBounds(bounds
) = self;
110 for (i
, bound
) in bounds
.iter().enumerate() {
114 fmt
::Display
::fmt(bound
, f
)?
;
120 impl fmt
::Display
for clean
::GenericParam
{
121 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
123 clean
::GenericParam
::Lifetime(ref lp
) => write
!(f
, "{}", lp
),
124 clean
::GenericParam
::Type(ref tp
) => {
125 f
.write_str(&tp
.name
)?
;
127 if !tp
.bounds
.is_empty() {
129 write
!(f
, ": {:#}", TyParamBounds(&tp
.bounds
))?
;
131 write
!(f
, ": {}", TyParamBounds(&tp
.bounds
))?
;
135 if let Some(ref ty
) = tp
.default {
137 write
!(f
, " = {:#}", ty
)?
;
139 write
!(f
, " = {}", ty
)?
;
149 impl fmt
::Display
for clean
::Generics
{
150 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
151 let real_params
= self.params
153 .filter(|p
| !p
.is_synthetic_type_param())
154 .collect
::<Vec
<_
>>();
155 if real_params
.is_empty() {
159 write
!(f
, "<{:#}>", CommaSep(&real_params
))
161 write
!(f
, "<{}>", CommaSep(&real_params
))
166 impl<'a
> fmt
::Display
for WhereClause
<'a
> {
167 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
168 let &WhereClause { gens, indent, end_newline }
= self;
169 if gens
.where_predicates
.is_empty() {
172 let mut clause
= String
::new();
174 clause
.push_str(" where");
177 clause
.push_str(" <span class=\"where fmt-newline\">where");
179 clause
.push_str(" <span class=\"where\">where");
182 for (i
, pred
) in gens
.where_predicates
.iter().enumerate() {
186 clause
.push_str("<br>");
190 &clean
::WherePredicate
::BoundPredicate { ref ty, ref bounds }
=> {
193 clause
.push_str(&format
!("{:#}: {:#}", ty
, TyParamBounds(bounds
)));
195 clause
.push_str(&format
!("{}: {}", ty
, TyParamBounds(bounds
)));
198 &clean
::WherePredicate
::RegionPredicate
{ ref lifetime
,
200 clause
.push_str(&format
!("{}: ", lifetime
));
201 for (i
, lifetime
) in bounds
.iter().enumerate() {
203 clause
.push_str(" + ");
206 clause
.push_str(&format
!("{}", lifetime
));
209 &clean
::WherePredicate
::EqPredicate { ref lhs, ref rhs }
=> {
211 clause
.push_str(&format
!("{:#} == {:#}", lhs
, rhs
));
213 clause
.push_str(&format
!("{} == {}", lhs
, rhs
));
218 if i
< gens
.where_predicates
.len() - 1 || end_newline
{
224 // add a space so stripping <br> tags and breaking spaces still renders properly
228 clause
.push_str(" ");
233 clause
.push_str("</span>");
234 let padding
= repeat(" ").take(indent
+ 4).collect
::<String
>();
235 clause
= clause
.replace("<br>", &format
!("<br>{}", padding
));
236 clause
.insert_str(0, &repeat(" ").take(indent
.saturating_sub(1))
237 .collect
::<String
>());
239 clause
.insert_str(0, "<br>");
242 write
!(f
, "{}", clause
)
246 impl fmt
::Display
for clean
::Lifetime
{
247 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
248 f
.write_str(self.get_ref())?
;
253 impl fmt
::Display
for clean
::PolyTrait
{
254 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
255 if !self.generic_params
.is_empty() {
257 write
!(f
, "for<{:#}> ", CommaSep(&self.generic_params
))?
;
259 write
!(f
, "for<{}> ", CommaSep(&self.generic_params
))?
;
263 write
!(f
, "{:#}", self.trait_
)
265 write
!(f
, "{}", self.trait_
)
270 impl fmt
::Display
for clean
::TyParamBound
{
271 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
273 clean
::RegionBound(ref lt
) => {
276 clean
::TraitBound(ref ty
, modifier
) => {
277 let modifier_str
= match modifier
{
278 hir
::TraitBoundModifier
::None
=> "",
279 hir
::TraitBoundModifier
::Maybe
=> "?",
282 write
!(f
, "{}{:#}", modifier_str
, *ty
)
284 write
!(f
, "{}{}", modifier_str
, *ty
)
291 impl fmt
::Display
for clean
::PathParameters
{
292 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
294 clean
::PathParameters
::AngleBracketed
{
295 ref lifetimes
, ref types
, ref bindings
297 if !lifetimes
.is_empty() || !types
.is_empty() || !bindings
.is_empty() {
301 f
.write_str("<")?
;
303 let mut comma
= false;
304 for lifetime
in lifetimes
{
309 write
!(f
, "{}", *lifetime
)?
;
317 write
!(f
, "{:#}", *ty
)?
;
319 write
!(f
, "{}", *ty
)?
;
322 for binding
in bindings
{
328 write
!(f
, "{:#}", *binding
)?
;
330 write
!(f
, "{}", *binding
)?
;
336 f
.write_str(">")?
;
340 clean
::PathParameters
::Parenthesized { ref inputs, ref output }
=> {
342 let mut comma
= false;
349 write
!(f
, "{:#}", *ty
)?
;
351 write
!(f
, "{}", *ty
)?
;
355 if let Some(ref ty
) = *output
{
357 write
!(f
, " -> {:#}", ty
)?
;
359 write
!(f
, " -> {}", ty
)?
;
368 impl fmt
::Display
for clean
::PathSegment
{
369 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
370 f
.write_str(&self.name
)?
;
372 write
!(f
, "{:#}", self.params
)
374 write
!(f
, "{}", self.params
)
379 impl fmt
::Display
for clean
::Path
{
380 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
385 for (i
, seg
) in self.segments
.iter().enumerate() {
390 write
!(f
, "{:#}", seg
)?
;
392 write
!(f
, "{}", seg
)?
;
399 pub fn href(did
: DefId
) -> Option
<(String
, ItemType
, Vec
<String
>)> {
401 if !did
.is_local() && !cache
.access_levels
.is_doc_reachable(did
) {
405 let loc
= CURRENT_LOCATION_KEY
.with(|l
| l
.borrow().clone());
406 let (fqp
, shortty
, mut url
) = match cache
.paths
.get(&did
) {
407 Some(&(ref fqp
, shortty
)) => {
408 (fqp
, shortty
, repeat("../").take(loc
.len()).collect())
411 let &(ref fqp
, shortty
) = cache
.external_paths
.get(&did
)?
;
412 (fqp
, shortty
, match cache
.extern_locations
[&did
.krate
] {
413 (.., render
::Remote(ref s
)) => s
.to_string(),
414 (.., render
::Local
) => repeat("../").take(loc
.len()).collect(),
415 (.., render
::Unknown
) => return None
,
419 for component
in &fqp
[..fqp
.len() - 1] {
420 url
.push_str(component
);
424 ItemType
::Module
=> {
425 url
.push_str(fqp
.last().unwrap());
426 url
.push_str("/index.html");
429 url
.push_str(shortty
.css_class());
431 url
.push_str(fqp
.last().unwrap());
432 url
.push_str(".html");
435 Some((url
, shortty
, fqp
.to_vec()))
438 /// Used when rendering a `ResolvedPath` structure. This invokes the `path`
439 /// rendering function with the necessary arguments for linking to a local path.
440 fn resolved_path(w
: &mut fmt
::Formatter
, did
: DefId
, path
: &clean
::Path
,
441 print_all
: bool
, use_absolute
: bool
) -> fmt
::Result
{
442 let last
= path
.segments
.last().unwrap();
445 for seg
in &path
.segments
[..path
.segments
.len() - 1] {
446 write
!(w
, "{}::", seg
.name
)?
;
450 write
!(w
, "{:#}{:#}", HRef
::new(did
, &last
.name
), last
.params
)?
;
452 let path
= if use_absolute
{
454 Some((_
, _
, fqp
)) => {
456 fqp
[..fqp
.len() - 1].join("::"),
457 HRef
::new(did
, fqp
.last().unwrap()))
459 None
=> format
!("{}", HRef
::new(did
, &last
.name
)),
462 format
!("{}", HRef
::new(did
, &last
.name
))
464 write
!(w
, "{}{}", path
, last
.params
)?
;
469 fn primitive_link(f
: &mut fmt
::Formatter
,
470 prim
: clean
::PrimitiveType
,
471 name
: &str) -> fmt
::Result
{
473 let mut needs_termination
= false;
475 match m
.primitive_locations
.get(&prim
) {
476 Some(&def_id
) if def_id
.is_local() => {
477 let len
= CURRENT_LOCATION_KEY
.with(|s
| s
.borrow().len());
478 let len
= if len
== 0 {0}
else {len - 1}
;
479 write
!(f
, "<a class=\"primitive\" href=\"{}primitive.{}.html\">",
480 repeat("../").take(len
).collect
::<String
>(),
482 needs_termination
= true;
485 let loc
= match m
.extern_locations
[&def_id
.krate
] {
486 (ref cname
, _
, render
::Remote(ref s
)) => {
487 Some((cname
, s
.to_string()))
489 (ref cname
, _
, render
::Local
) => {
490 let len
= CURRENT_LOCATION_KEY
.with(|s
| s
.borrow().len());
491 Some((cname
, repeat("../").take(len
).collect
::<String
>()))
493 (.., render
::Unknown
) => None
,
495 if let Some((cname
, root
)) = loc
{
496 write
!(f
, "<a class=\"primitive\" href=\"{}{}/primitive.{}.html\">",
500 needs_termination
= true;
506 write
!(f
, "{}", name
)?
;
507 if needs_termination
{
513 /// Helper to render type parameters
514 fn tybounds(w
: &mut fmt
::Formatter
,
515 typarams
: &Option
<Vec
<clean
::TyParamBound
>>) -> fmt
::Result
{
517 Some(ref params
) => {
518 for param
in params
{
520 fmt
::Display
::fmt(param
, w
)?
;
529 pub fn new(did
: DefId
, text
: &'a
str) -> HRef
<'a
> {
530 HRef { did: did, text: text }
534 impl<'a
> fmt
::Display
for HRef
<'a
> {
535 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
536 match href(self.did
) {
537 Some((url
, shortty
, fqp
)) => if !f
.alternate() {
538 write
!(f
, "<a class=\"{}\" href=\"{}\" title=\"{} {}\">{}</a>",
539 shortty
, url
, shortty
, fqp
.join("::"), self.text
)
541 write
!(f
, "{}", self.text
)
543 _
=> write
!(f
, "{}", self.text
),
548 fn fmt_type(t
: &clean
::Type
, f
: &mut fmt
::Formatter
, use_absolute
: bool
) -> fmt
::Result
{
550 clean
::Generic(ref name
) => {
553 clean
::ResolvedPath{ did, ref typarams, ref path, is_generic }
=> {
554 // Paths like T::Output and Self::Output should be rendered with all segments
555 resolved_path(f
, did
, path
, is_generic
, use_absolute
)?
;
556 tybounds(f
, typarams
)
558 clean
::Infer
=> write
!(f
, "_"),
559 clean
::Primitive(prim
) => primitive_link(f
, prim
, prim
.as_str()),
560 clean
::BareFunction(ref decl
) => {
562 write
!(f
, "{}{:#}fn{:#}{:#}",
563 UnsafetySpace(decl
.unsafety
),
565 CommaSep(&decl
.generic_params
),
568 write
!(f
, "{}{}", UnsafetySpace(decl
.unsafety
), AbiSpace(decl
.abi
))?
;
569 primitive_link(f
, PrimitiveType
::Fn
, "fn")?
;
570 write
!(f
, "{}{}", CommaSep(&decl
.generic_params
), decl
.decl
)
573 clean
::Tuple(ref typs
) => {
575 &[] => primitive_link(f
, PrimitiveType
::Unit
, "()"),
577 primitive_link(f
, PrimitiveType
::Tuple
, "(")?
;
578 //carry f.alternate() into this display w/o branching manually
579 fmt
::Display
::fmt(one
, f
)?
;
580 primitive_link(f
, PrimitiveType
::Tuple
, ",)")
583 primitive_link(f
, PrimitiveType
::Tuple
, "(")?
;
584 fmt
::Display
::fmt(&CommaSep(many
), f
)?
;
585 primitive_link(f
, PrimitiveType
::Tuple
, ")")
589 clean
::Slice(ref t
) => {
590 primitive_link(f
, PrimitiveType
::Slice
, "[")?
;
591 fmt
::Display
::fmt(t
, f
)?
;
592 primitive_link(f
, PrimitiveType
::Slice
, "]")
594 clean
::Array(ref t
, ref n
) => {
595 primitive_link(f
, PrimitiveType
::Array
, "[")?
;
596 fmt
::Display
::fmt(t
, f
)?
;
597 primitive_link(f
, PrimitiveType
::Array
, &format
!("; {}]", n
))
599 clean
::Never
=> primitive_link(f
, PrimitiveType
::Never
, "!"),
600 clean
::RawPointer(m
, ref t
) => {
602 clean
::Generic(_
) | clean
::ResolvedPath {is_generic: true, ..}
=> {
604 primitive_link(f
, clean
::PrimitiveType
::RawPointer
,
605 &format
!("*{}{:#}", RawMutableSpace(m
), t
))
607 primitive_link(f
, clean
::PrimitiveType
::RawPointer
,
608 &format
!("*{}{}", RawMutableSpace(m
), t
))
612 primitive_link(f
, clean
::PrimitiveType
::RawPointer
,
613 &format
!("*{}", RawMutableSpace(m
)))?
;
614 fmt
::Display
::fmt(t
, f
)
618 clean
::BorrowedRef{ lifetime: ref l, mutability, type_: ref ty}
=> {
620 Some(ref l
) => format
!("{} ", *l
),
623 let m
= MutableSpace(mutability
);
624 let amp
= if f
.alternate() {
630 clean
::Slice(ref bt
) => { // BorrowedRef{ ... Slice(T) } is
&[T
]
632 clean
::Generic(_
) => {
634 primitive_link(f
, PrimitiveType
::Slice
,
635 &format
!("{}{}{}[{:#}]", amp
, lt
, m
, **bt
))
637 primitive_link(f
, PrimitiveType
::Slice
,
638 &format
!("{}{}{}[{}]", amp
, lt
, m
, **bt
))
642 primitive_link(f
, PrimitiveType
::Slice
,
643 &format
!("{}{}{}[", amp
, lt
, m
))?
;
645 write
!(f
, "{:#}", **bt
)?
;
647 write
!(f
, "{}", **bt
)?
;
649 primitive_link(f
, PrimitiveType
::Slice
, "]")
653 clean
::ResolvedPath { typarams: Some(ref v), .. }
if !v
.is_empty() => {
654 write
!(f
, "{}{}{}(", amp
, lt
, m
)?
;
655 fmt_type(&ty
, f
, use_absolute
)?
;
658 clean
::Generic(..) => {
659 primitive_link(f
, PrimitiveType
::Reference
,
660 &format
!("{}{}{}", amp
, lt
, m
))?
;
661 fmt_type(&ty
, f
, use_absolute
)
664 write
!(f
, "{}{}{}", amp
, lt
, m
)?
;
665 fmt_type(&ty
, f
, use_absolute
)
669 clean
::ImplTrait(ref bounds
) => {
670 write
!(f
, "impl {}", TyParamBounds(bounds
))
672 clean
::QPath { ref name, ref self_type, ref trait_ }
=> {
673 let should_show_cast
= match *trait_
{
674 box clean
::ResolvedPath { ref path, .. }
=> {
675 !path
.segments
.is_empty() && !self_type
.is_self_type()
680 if should_show_cast
{
681 write
!(f
, "<{:#} as {:#}>::", self_type
, trait_
)?
683 write
!(f
, "{:#}::", self_type
)?
686 if should_show_cast
{
687 write
!(f
, "<{} as {}>::", self_type
, trait_
)?
689 write
!(f
, "{}::", self_type
)?
693 // It's pretty unsightly to look at `<A as B>::C` in output, and
694 // we've got hyperlinking on our side, so try to avoid longer
695 // notation as much as possible by making `C` a hyperlink to trait
696 // `B` to disambiguate.
698 // FIXME: this is still a lossy conversion and there should probably
699 // be a better way of representing this in general? Most of
700 // the ugliness comes from inlining across crates where
701 // everything comes in as a fully resolved QPath (hard to
703 box clean
::ResolvedPath { did, ref typarams, .. }
=> {
705 Some((ref url
, _
, ref path
)) if !f
.alternate() => {
707 "<a class=\"type\" href=\"{url}#{shortty}.{name}\" \
708 title=\"type {path}::{name}\">{name}</a>",
710 shortty
= ItemType
::AssociatedType
,
712 path
= path
.join("::"))?
;
714 _
=> write
!(f
, "{}", name
)?
,
717 // FIXME: `typarams` are not rendered, and this seems bad?
722 write
!(f
, "{}", name
)
726 clean
::Unique(..) => {
727 panic
!("should have been cleaned")
732 impl fmt
::Display
for clean
::Type
{
733 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
734 fmt_type(self, f
, false)
738 fn fmt_impl(i
: &clean
::Impl
,
739 f
: &mut fmt
::Formatter
,
741 use_absolute
: bool
) -> fmt
::Result
{
743 write
!(f
, "impl{:#} ", i
.generics
)?
;
745 write
!(f
, "impl{} ", i
.generics
)?
;
748 if let Some(ref ty
) = i
.trait_
{
749 if i
.polarity
== Some(clean
::ImplPolarity
::Negative
) {
754 fmt
::Display
::fmt(ty
, f
)?
;
757 clean
::ResolvedPath { typarams: None, ref path, is_generic: false, .. }
=> {
758 let last
= path
.segments
.last().unwrap();
759 fmt
::Display
::fmt(&last
.name
, f
)?
;
760 fmt
::Display
::fmt(&last
.params
, f
)?
;
768 fmt_type(&i
.for_
, f
, use_absolute
)?
;
770 fmt
::Display
::fmt(&WhereClause { gens: &i.generics, indent: 0, end_newline: true }
, f
)?
;
774 impl fmt
::Display
for clean
::Impl
{
775 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
776 fmt_impl(self, f
, true, false)
780 // The difference from above is that trait is not hyperlinked.
781 pub fn fmt_impl_for_trait_page(i
: &clean
::Impl
,
782 f
: &mut fmt
::Formatter
,
783 use_absolute
: bool
) -> fmt
::Result
{
784 fmt_impl(i
, f
, false, use_absolute
)
787 impl fmt
::Display
for clean
::Arguments
{
788 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
789 for (i
, input
) in self.values
.iter().enumerate() {
790 if !input
.name
.is_empty() {
791 write
!(f
, "{}: ", input
.name
)?
;
794 write
!(f
, "{:#}", input
.type_
)?
;
796 write
!(f
, "{}", input
.type_
)?
;
798 if i
+ 1 < self.values
.len() { write!(f, ", ")?; }
804 impl fmt
::Display
for clean
::FunctionRetTy
{
805 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
807 clean
::Return(clean
::Tuple(ref tys
)) if tys
.is_empty() => Ok(()),
808 clean
::Return(ref ty
) if f
.alternate() => write
!(f
, " -> {:#}", ty
),
809 clean
::Return(ref ty
) => write
!(f
, " -> {}", ty
),
810 clean
::DefaultReturn
=> Ok(()),
815 impl fmt
::Display
for clean
::FnDecl
{
816 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
819 write
!(f
, "({args:#}, ...){arrow:#}", args
= self.inputs
, arrow
= self.output
)
821 write
!(f
, "({args}, ...){arrow}", args
= self.inputs
, arrow
= self.output
)
825 write
!(f
, "({args:#}){arrow:#}", args
= self.inputs
, arrow
= self.output
)
827 write
!(f
, "({args}){arrow}", args
= self.inputs
, arrow
= self.output
)
833 impl<'a
> fmt
::Display
for Method
<'a
> {
834 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
835 let &Method { decl, name_len, indent }
= self;
836 let amp
= if f
.alternate() { "&" }
else { "&" }
;
837 let mut args
= String
::new();
838 let mut args_plain
= String
::new();
839 for (i
, input
) in decl
.inputs
.values
.iter().enumerate() {
841 args
.push_str("<br>");
844 if let Some(selfty
) = input
.to_self() {
846 clean
::SelfValue
=> {
847 args
.push_str("self");
848 args_plain
.push_str("self");
850 clean
::SelfBorrowed(Some(ref lt
), mtbl
) => {
851 args
.push_str(&format
!("{}{} {}self", amp
, *lt
, MutableSpace(mtbl
)));
852 args_plain
.push_str(&format
!("&{} {}self", *lt
, MutableSpace(mtbl
)));
854 clean
::SelfBorrowed(None
, mtbl
) => {
855 args
.push_str(&format
!("{}{}self", amp
, MutableSpace(mtbl
)));
856 args_plain
.push_str(&format
!("&{}self", MutableSpace(mtbl
)));
858 clean
::SelfExplicit(ref typ
) => {
860 args
.push_str(&format
!("self: {:#}", *typ
));
862 args
.push_str(&format
!("self: {}", *typ
));
864 args_plain
.push_str(&format
!("self: {:#}", *typ
));
869 args
.push_str(" <br>");
870 args_plain
.push_str(" ");
872 if !input
.name
.is_empty() {
873 args
.push_str(&format
!("{}: ", input
.name
));
874 args_plain
.push_str(&format
!("{}: ", input
.name
));
878 args
.push_str(&format
!("{:#}", input
.type_
));
880 args
.push_str(&format
!("{}", input
.type_
));
882 args_plain
.push_str(&format
!("{:#}", input
.type_
));
884 if i
+ 1 < decl
.inputs
.values
.len() {
886 args_plain
.push('
,'
);
891 args
.push_str(",<br> ...");
892 args_plain
.push_str(", ...");
895 let arrow_plain
= format
!("{:#}", decl
.output
);
896 let arrow
= if f
.alternate() {
897 format
!("{:#}", decl
.output
)
899 format
!("{}", decl
.output
)
902 let pad
= repeat(" ").take(name_len
).collect
::<String
>();
903 let plain
= format
!("{pad}({args}){arrow}",
906 arrow
= arrow_plain
);
908 let output
= if plain
.len() > 80 {
909 let full_pad
= format
!("<br>{}", repeat(" ").take(indent
+ 4).collect
::<String
>());
910 let close_pad
= format
!("<br>{}", repeat(" ").take(indent
).collect
::<String
>());
911 format
!("({args}{close}){arrow}",
912 args
= args
.replace("<br>", &full_pad
),
916 format
!("({args}){arrow}", args
= args
.replace("<br>", ""), arrow
= arrow
)
920 write
!(f
, "{}", output
.replace("<br>", "\n"))
922 write
!(f
, "{}", output
)
927 impl<'a
> fmt
::Display
for VisSpace
<'a
> {
928 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
930 Some(clean
::Public
) => write
!(f
, "pub "),
931 Some(clean
::Inherited
) | None
=> Ok(())
936 impl fmt
::Display
for UnsafetySpace
{
937 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
939 hir
::Unsafety
::Unsafe
=> write
!(f
, "unsafe "),
940 hir
::Unsafety
::Normal
=> Ok(())
945 impl fmt
::Display
for ConstnessSpace
{
946 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
948 hir
::Constness
::Const
=> write
!(f
, "const "),
949 hir
::Constness
::NotConst
=> Ok(())
954 impl fmt
::Display
for clean
::Import
{
955 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
957 clean
::Import
::Simple(ref name
, ref src
) => {
958 if *name
== src
.path
.last_name() {
959 write
!(f
, "use {};", *src
)
961 write
!(f
, "use {} as {};", *src
, *name
)
964 clean
::Import
::Glob(ref src
) => {
965 if src
.path
.segments
.is_empty() {
968 write
!(f
, "use {}::*;", *src
)
975 impl fmt
::Display
for clean
::ImportSource
{
976 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
978 Some(did
) => resolved_path(f
, did
, &self.path
, true, false),
980 for (i
, seg
) in self.path
.segments
.iter().enumerate() {
984 write
!(f
, "{}", seg
.name
)?
;
992 impl fmt
::Display
for clean
::TypeBinding
{
993 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
995 write
!(f
, "{} = {:#}", self.name
, self.ty
)
997 write
!(f
, "{} = {}", self.name
, self.ty
)
1002 impl fmt
::Display
for MutableSpace
{
1003 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
1005 MutableSpace(clean
::Immutable
) => Ok(()),
1006 MutableSpace(clean
::Mutable
) => write
!(f
, "mut "),
1011 impl fmt
::Display
for RawMutableSpace
{
1012 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
1014 RawMutableSpace(clean
::Immutable
) => write
!(f
, "const "),
1015 RawMutableSpace(clean
::Mutable
) => write
!(f
, "mut "),
1020 impl fmt
::Display
for AbiSpace
{
1021 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
1022 let quot
= if f
.alternate() { "\"" }
else { """ }
;
1024 Abi
::Rust
=> Ok(()),
1025 abi
=> write
!(f
, "extern {0}{1}{0} ", quot
, abi
.name()),