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, LOCAL_CRATE}
;
25 use clean
::{self, PrimitiveType}
;
26 use core
::DocAccessLevels
;
27 use html
::item_type
::ItemType
;
28 use html
::escape
::Escape
;
30 use html
::render
::{cache, CURRENT_LOCATION_KEY}
;
32 /// Helper to render an optional visibility with a space after it (if the
33 /// visibility is preset)
34 #[derive(Copy, Clone)]
35 pub struct VisSpace
<'a
>(pub &'a Option
<clean
::Visibility
>);
36 /// Similarly to VisSpace, this structure is used to render a function style with a
38 #[derive(Copy, Clone)]
39 pub struct UnsafetySpace(pub hir
::Unsafety
);
40 /// Similarly to VisSpace, this structure is used to render a function constness
41 /// with a space after it.
42 #[derive(Copy, Clone)]
43 pub struct ConstnessSpace(pub hir
::Constness
);
44 /// Wrapper struct for properly emitting a method declaration.
45 pub struct Method
<'a
>(pub &'a clean
::FnDecl
, pub &'a
str);
46 /// Similar to VisSpace, but used for mutability
47 #[derive(Copy, Clone)]
48 pub struct MutableSpace(pub clean
::Mutability
);
49 /// Similar to VisSpace, but used for mutability
50 #[derive(Copy, Clone)]
51 pub struct RawMutableSpace(pub clean
::Mutability
);
52 /// Wrapper struct for emitting a where clause from Generics.
53 pub struct WhereClause
<'a
>(pub &'a clean
::Generics
);
54 /// Wrapper struct for emitting type parameter bounds.
55 pub struct TyParamBounds
<'a
>(pub &'a
[clean
::TyParamBound
]);
56 /// Wrapper struct for emitting a comma-separated list of items
57 pub struct CommaSep
<'a
, T
: 'a
>(pub &'a
[T
]);
58 pub struct AbiSpace(pub Abi
);
65 impl<'a
> VisSpace
<'a
> {
66 pub fn get(self) -> &'a Option
<clean
::Visibility
> {
67 let VisSpace(v
) = self; v
72 pub fn get(&self) -> hir
::Unsafety
{
73 let UnsafetySpace(v
) = *self; v
78 pub fn get(&self) -> hir
::Constness
{
79 let ConstnessSpace(v
) = *self; v
83 impl<'a
, T
: fmt
::Display
> fmt
::Display
for CommaSep
<'a
, T
> {
84 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
85 for (i
, item
) in self.0.iter
().enumerate() {
86 if i
!= 0 { write!(f, ", ")?; }
87 fmt
::Display
::fmt(item
, f
)?
;
93 impl<'a
> fmt
::Display
for TyParamBounds
<'a
> {
94 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
95 let &TyParamBounds(bounds
) = self;
96 for (i
, bound
) in bounds
.iter().enumerate() {
100 fmt
::Display
::fmt(bound
, f
)?
;
106 impl fmt
::Display
for clean
::Generics
{
107 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
108 if self.lifetimes
.is_empty() && self.type_params
.is_empty() { return Ok(()) }
112 f
.write_str("<")?
;
115 for (i
, life
) in self.lifetimes
.iter().enumerate() {
119 write
!(f
, "{}", *life
)?
;
122 if !self.type_params
.is_empty() {
123 if !self.lifetimes
.is_empty() {
126 for (i
, tp
) in self.type_params
.iter().enumerate() {
130 f
.write_str(&tp
.name
)?
;
132 if !tp
.bounds
.is_empty() {
134 write
!(f
, ": {:#}", TyParamBounds(&tp
.bounds
))?
;
136 write
!(f
, ": {}", TyParamBounds(&tp
.bounds
))?
;
140 if let Some(ref ty
) = tp
.default {
142 write
!(f
, " = {:#}", ty
)?
;
144 write
!(f
, " = {}", ty
)?
;
152 f
.write_str(">")?
;
158 impl<'a
> fmt
::Display
for WhereClause
<'a
> {
159 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
160 let &WhereClause(gens
) = self;
161 if gens
.where_predicates
.is_empty() {
167 f
.write_str(" <span class='where'>where ")?
;
169 for (i
, pred
) in gens
.where_predicates
.iter().enumerate() {
174 &clean
::WherePredicate
::BoundPredicate { ref ty, ref bounds }
=> {
177 write
!(f
, "{:#}: {:#}", ty
, TyParamBounds(bounds
))?
;
179 write
!(f
, "{}: {}", ty
, TyParamBounds(bounds
))?
;
182 &clean
::WherePredicate
::RegionPredicate
{ ref lifetime
,
184 write
!(f
, "{}: ", lifetime
)?
;
185 for (i
, lifetime
) in bounds
.iter().enumerate() {
190 write
!(f
, "{}", lifetime
)?
;
193 &clean
::WherePredicate
::EqPredicate { ref lhs, ref rhs }
=> {
195 write
!(f
, "{:#} == {:#}", lhs
, rhs
)?
;
197 write
!(f
, "{} == {}", lhs
, rhs
)?
;
203 f
.write_str("</span>")?
;
209 impl fmt
::Display
for clean
::Lifetime
{
210 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
211 f
.write_str(self.get_ref())?
;
216 impl fmt
::Display
for clean
::PolyTrait
{
217 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
218 if !self.lifetimes
.is_empty() {
220 f
.write_str("for<")?
;
222 f
.write_str("for<")?
;
224 for (i
, lt
) in self.lifetimes
.iter().enumerate() {
228 write
!(f
, "{}", lt
)?
;
233 f
.write_str("> ")?
;
237 write
!(f
, "{:#}", self.trait_
)
239 write
!(f
, "{}", self.trait_
)
244 impl fmt
::Display
for clean
::TyParamBound
{
245 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
247 clean
::RegionBound(ref lt
) => {
250 clean
::TraitBound(ref ty
, modifier
) => {
251 let modifier_str
= match modifier
{
252 hir
::TraitBoundModifier
::None
=> "",
253 hir
::TraitBoundModifier
::Maybe
=> "?",
256 write
!(f
, "{}{:#}", modifier_str
, *ty
)
258 write
!(f
, "{}{}", modifier_str
, *ty
)
265 impl fmt
::Display
for clean
::PathParameters
{
266 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
268 clean
::PathParameters
::AngleBracketed
{
269 ref lifetimes
, ref types
, ref bindings
271 if !lifetimes
.is_empty() || !types
.is_empty() || !bindings
.is_empty() {
275 f
.write_str("<")?
;
277 let mut comma
= false;
278 for lifetime
in lifetimes
{
283 write
!(f
, "{}", *lifetime
)?
;
291 write
!(f
, "{:#}", *ty
)?
;
293 write
!(f
, "{}", *ty
)?
;
296 for binding
in bindings
{
302 write
!(f
, "{:#}", *binding
)?
;
304 write
!(f
, "{}", *binding
)?
;
310 f
.write_str(">")?
;
314 clean
::PathParameters
::Parenthesized { ref inputs, ref output }
=> {
316 let mut comma
= false;
323 write
!(f
, "{:#}", *ty
)?
;
325 write
!(f
, "{}", *ty
)?
;
329 if let Some(ref ty
) = *output
{
331 write
!(f
, " -> {:#}", ty
)?
;
333 write
!(f
, " -> {}", ty
)?
;
342 impl fmt
::Display
for clean
::PathSegment
{
343 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
344 f
.write_str(&self.name
)?
;
346 write
!(f
, "{:#}", self.params
)
348 write
!(f
, "{}", self.params
)
353 impl fmt
::Display
for clean
::Path
{
354 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
359 for (i
, seg
) in self.segments
.iter().enumerate() {
364 write
!(f
, "{:#}", seg
)?
;
366 write
!(f
, "{}", seg
)?
;
373 pub fn href(did
: DefId
) -> Option
<(String
, ItemType
, Vec
<String
>)> {
375 if !did
.is_local() && !cache
.access_levels
.is_doc_reachable(did
) {
379 let loc
= CURRENT_LOCATION_KEY
.with(|l
| l
.borrow().clone());
380 let (fqp
, shortty
, mut url
) = match cache
.paths
.get(&did
) {
381 Some(&(ref fqp
, shortty
)) => {
382 (fqp
, shortty
, repeat("../").take(loc
.len()).collect())
384 None
=> match cache
.external_paths
.get(&did
) {
385 Some(&(ref fqp
, shortty
)) => {
386 (fqp
, shortty
, match cache
.extern_locations
[&did
.krate
] {
387 (_
, render
::Remote(ref s
)) => s
.to_string(),
388 (_
, render
::Local
) => repeat("../").take(loc
.len()).collect(),
389 (_
, render
::Unknown
) => return None
,
395 for component
in &fqp
[..fqp
.len() - 1] {
396 url
.push_str(component
);
400 ItemType
::Module
=> {
401 url
.push_str(fqp
.last().unwrap());
402 url
.push_str("/index.html");
405 url
.push_str(shortty
.css_class());
407 url
.push_str(fqp
.last().unwrap());
408 url
.push_str(".html");
411 Some((url
, shortty
, fqp
.to_vec()))
414 /// Used when rendering a `ResolvedPath` structure. This invokes the `path`
415 /// rendering function with the necessary arguments for linking to a local path.
416 fn resolved_path(w
: &mut fmt
::Formatter
, did
: DefId
, path
: &clean
::Path
,
417 print_all
: bool
) -> fmt
::Result
{
418 let last
= path
.segments
.last().unwrap();
419 let rel_root
= match &*path
.segments
[0].name
{
420 "self" => Some("./".to_string()),
425 let amt
= path
.segments
.len() - 1;
428 for seg
in &path
.segments
[..amt
] {
429 if "super" == seg
.name
|| "self" == seg
.name
|| w
.alternate() {
430 write
!(w
, "{}::", seg
.name
)?
;
432 root
.push_str(&seg
.name
);
434 write
!(w
, "<a class='mod'
435 href='{}index.html'>{}</a>::",
442 for seg
in &path
.segments
[..amt
] {
443 write
!(w
, "{}::", seg
.name
)?
;
449 write
!(w
, "{:#}{:#}", HRef
::new(did
, &last
.name
), last
.params
)?
;
451 write
!(w
, "{}{}", HRef
::new(did
, &last
.name
), last
.params
)?
;
456 fn primitive_link(f
: &mut fmt
::Formatter
,
457 prim
: clean
::PrimitiveType
,
458 name
: &str) -> fmt
::Result
{
460 let mut needs_termination
= false;
462 match m
.primitive_locations
.get(&prim
) {
463 Some(&LOCAL_CRATE
) => {
464 let len
= CURRENT_LOCATION_KEY
.with(|s
| s
.borrow().len());
465 let len
= if len
== 0 {0}
else {len - 1}
;
466 write
!(f
, "<a class='primitive' href='{}primitive.{}.html'>",
467 repeat("../").take(len
).collect
::<String
>(),
469 needs_termination
= true;
472 let loc
= match m
.extern_locations
[&cnum
] {
473 (ref cname
, render
::Remote(ref s
)) => Some((cname
, s
.to_string())),
474 (ref cname
, render
::Local
) => {
475 let len
= CURRENT_LOCATION_KEY
.with(|s
| s
.borrow().len());
476 Some((cname
, repeat("../").take(len
).collect
::<String
>()))
478 (_
, render
::Unknown
) => None
,
480 if let Some((cname
, root
)) = loc
{
481 write
!(f
, "<a class='primitive' href='{}{}/primitive.{}.html'>",
485 needs_termination
= true;
491 write
!(f
, "{}", name
)?
;
492 if needs_termination
{
498 /// Helper to render type parameters
499 fn tybounds(w
: &mut fmt
::Formatter
,
500 typarams
: &Option
<Vec
<clean
::TyParamBound
> >) -> fmt
::Result
{
502 Some(ref params
) => {
503 for param
in params
{
505 fmt
::Display
::fmt(param
, w
)?
;
514 pub fn new(did
: DefId
, text
: &'a
str) -> HRef
<'a
> {
515 HRef { did: did, text: text }
519 impl<'a
> fmt
::Display
for HRef
<'a
> {
520 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
521 match href(self.did
) {
522 Some((url
, shortty
, fqp
)) => if !f
.alternate() {
523 write
!(f
, "<a class='{}' href='{}' title='{}'>{}</a>",
524 shortty
, url
, fqp
.join("::"), self.text
)
526 write
!(f
, "{}", self.text
)
528 _
=> write
!(f
, "{}", self.text
),
533 impl fmt
::Display
for clean
::Type
{
534 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
536 clean
::Generic(ref name
) => {
539 clean
::ResolvedPath{ did, ref typarams, ref path, is_generic }
=> {
540 // Paths like T::Output and Self::Output should be rendered with all segments
541 resolved_path(f
, did
, path
, is_generic
)?
;
542 tybounds(f
, typarams
)
544 clean
::Infer
=> write
!(f
, "_"),
545 clean
::Primitive(prim
) => primitive_link(f
, prim
, prim
.as_str()),
546 clean
::BareFunction(ref decl
) => {
548 write
!(f
, "{}{}fn{:#}{:#}",
549 UnsafetySpace(decl
.unsafety
),
554 write
!(f
, "{}{}fn{}{}",
555 UnsafetySpace(decl
.unsafety
),
561 clean
::Tuple(ref typs
) => {
563 &[] => primitive_link(f
, PrimitiveType
::Tuple
, "()"),
565 primitive_link(f
, PrimitiveType
::Tuple
, "(")?
;
566 //carry f.alternate() into this display w/o branching manually
567 fmt
::Display
::fmt(one
, f
)?
;
568 primitive_link(f
, PrimitiveType
::Tuple
, ",)")
571 primitive_link(f
, PrimitiveType
::Tuple
, "(")?
;
572 fmt
::Display
::fmt(&CommaSep(&many
), f
)?
;
573 primitive_link(f
, PrimitiveType
::Tuple
, ")")
577 clean
::Vector(ref t
) => {
578 primitive_link(f
, PrimitiveType
::Slice
, &format
!("["))?
;
579 fmt
::Display
::fmt(t
, f
)?
;
580 primitive_link(f
, PrimitiveType
::Slice
, &format
!("]"))
582 clean
::FixedVector(ref t
, ref s
) => {
583 primitive_link(f
, PrimitiveType
::Array
, "[")?
;
584 fmt
::Display
::fmt(t
, f
)?
;
586 primitive_link(f
, PrimitiveType
::Array
,
587 &format
!("; {}]", s
))
589 primitive_link(f
, PrimitiveType
::Array
,
590 &format
!("; {}]", Escape(s
)))
593 clean
::Never
=> f
.write_str("!"),
594 clean
::RawPointer(m
, ref t
) => {
596 clean
::Generic(_
) | clean
::ResolvedPath {is_generic: true, ..}
=> {
598 primitive_link(f
, clean
::PrimitiveType
::RawPointer
,
599 &format
!("*{}{:#}", RawMutableSpace(m
), t
))
601 primitive_link(f
, clean
::PrimitiveType
::RawPointer
,
602 &format
!("*{}{}", RawMutableSpace(m
), t
))
606 primitive_link(f
, clean
::PrimitiveType
::RawPointer
,
607 &format
!("*{}", RawMutableSpace(m
)))?
;
608 fmt
::Display
::fmt(t
, f
)
612 clean
::BorrowedRef{ lifetime: ref l, mutability, type_: ref ty}
=> {
614 Some(ref l
) => format
!("{} ", *l
),
617 let m
= MutableSpace(mutability
);
619 clean
::Vector(ref bt
) => { // BorrowedRef{ ... Vector(T) } is
&[T
]
623 primitive_link(f
, PrimitiveType
::Slice
,
624 &format
!("&{}{}[{:#}]", lt
, m
, **bt
))
626 primitive_link(f
, PrimitiveType
::Slice
,
627 &format
!("&{}{}[{}]", lt
, m
, **bt
))
631 primitive_link(f
, PrimitiveType
::Slice
,
632 &format
!("&{}{}[", lt
, m
))?
;
633 write
!(f
, "{:#}", **bt
)?
;
635 primitive_link(f
, PrimitiveType
::Slice
,
636 &format
!("&{}{}[", lt
, m
))?
;
637 write
!(f
, "{}", **bt
)?
;
639 primitive_link(f
, PrimitiveType
::Slice
, "]")
645 write
!(f
, "&{}{}{:#}", lt
, m
, **ty
)
647 write
!(f
, "&{}{}{}", lt
, m
, **ty
)
652 clean
::PolyTraitRef(ref bounds
) => {
653 for (i
, bound
) in bounds
.iter().enumerate() {
658 write
!(f
, "{:#}", *bound
)?
;
660 write
!(f
, "{}", *bound
)?
;
665 clean
::ImplTrait(ref bounds
) => {
667 for (i
, bound
) in bounds
.iter().enumerate() {
672 write
!(f
, "{:#}", *bound
)?
;
674 write
!(f
, "{}", *bound
)?
;
679 // It's pretty unsightly to look at `<A as B>::C` in output, and
680 // we've got hyperlinking on our side, so try to avoid longer
681 // notation as much as possible by making `C` a hyperlink to trait
682 // `B` to disambiguate.
684 // FIXME: this is still a lossy conversion and there should probably
685 // be a better way of representing this in general? Most of
686 // the ugliness comes from inlining across crates where
687 // everything comes in as a fully resolved QPath (hard to
692 trait_
: box clean
::ResolvedPath { did, ref typarams, .. }
,
695 write
!(f
, "{:#}::", self_type
)?
;
697 write
!(f
, "{}::", self_type
)?
;
699 let path
= clean
::Path
::singleton(name
.clone());
700 resolved_path(f
, did
, &path
, false)?
;
702 // FIXME: `typarams` are not rendered, and this seems bad?
706 clean
::QPath { ref name, ref self_type, ref trait_ }
=> {
708 write
!(f
, "<{:#} as {:#}>::{}", self_type
, trait_
, name
)
710 write
!(f
, "<{} as {}>::{}", self_type
, trait_
, name
)
713 clean
::Unique(..) => {
714 panic
!("should have been cleaned")
720 fn fmt_impl(i
: &clean
::Impl
, f
: &mut fmt
::Formatter
, link_trait
: bool
) -> fmt
::Result
{
722 write
!(f
, "impl{:#} ", i
.generics
)?
;
724 write
!(f
, "impl{} ", i
.generics
)?
;
726 if let Some(ref ty
) = i
.trait_
{
728 if i
.polarity
== Some(clean
::ImplPolarity
::Negative
) { "!" }
else { "" }
)?
;
730 fmt
::Display
::fmt(ty
, f
)?
;
733 clean
::ResolvedPath{ typarams: None, ref path, is_generic: false, .. }
=> {
734 let last
= path
.segments
.last().unwrap();
735 fmt
::Display
::fmt(&last
.name
, f
)?
;
736 fmt
::Display
::fmt(&last
.params
, f
)?
;
743 fmt
::Display
::fmt(&i
.for_
, f
)?
;
744 fmt
::Display
::fmt(&WhereClause(&i
.generics
), f
)?
;
748 impl fmt
::Display
for clean
::Impl
{
749 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
750 fmt_impl(self, f
, true)
754 // The difference from above is that trait is not hyperlinked.
755 pub fn fmt_impl_for_trait_page(i
: &clean
::Impl
, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
756 fmt_impl(i
, f
, false)
759 impl fmt
::Display
for clean
::Arguments
{
760 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
761 for (i
, input
) in self.values
.iter().enumerate() {
762 if !input
.name
.is_empty() {
763 write
!(f
, "{}: ", input
.name
)?
;
766 write
!(f
, "{:#}", input
.type_
)?
;
768 write
!(f
, "{}", input
.type_
)?
;
770 if i
+ 1 < self.values
.len() { write!(f, ", ")?; }
776 impl fmt
::Display
for clean
::FunctionRetTy
{
777 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
779 clean
::Return(clean
::Tuple(ref tys
)) if tys
.is_empty() => Ok(()),
780 clean
::Return(ref ty
) if f
.alternate() => write
!(f
, " -> {:#}", ty
),
781 clean
::Return(ref ty
) => write
!(f
, " -> {}", ty
),
782 clean
::DefaultReturn
=> Ok(()),
787 impl fmt
::Display
for clean
::FnDecl
{
788 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
791 write
!(f
, "({args:#}, ...){arrow:#}", args
= self.inputs
, arrow
= self.output
)
793 write
!(f
, "({args}, ...){arrow}", args
= self.inputs
, arrow
= self.output
)
797 write
!(f
, "({args:#}){arrow:#}", args
= self.inputs
, arrow
= self.output
)
799 write
!(f
, "({args}){arrow}", args
= self.inputs
, arrow
= self.output
)
805 impl<'a
> fmt
::Display
for Method
<'a
> {
806 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
809 let amp
= if f
.alternate() { "&" }
else { "&" }
;
810 let mut args
= String
::new();
811 let mut args_plain
= String
::new();
812 for (i
, input
) in decl
.inputs
.values
.iter().enumerate() {
813 if let Some(selfty
) = input
.to_self() {
815 clean
::SelfValue
=> {
816 args
.push_str("self");
817 args_plain
.push_str("self");
819 clean
::SelfBorrowed(Some(ref lt
), mtbl
) => {
820 args
.push_str(&format
!("{}{} {}self", amp
, *lt
, MutableSpace(mtbl
)));
821 args_plain
.push_str(&format
!("&{} {}self", *lt
, MutableSpace(mtbl
)));
823 clean
::SelfBorrowed(None
, mtbl
) => {
824 args
.push_str(&format
!("{}{}self", amp
, MutableSpace(mtbl
)));
825 args_plain
.push_str(&format
!("&{}self", MutableSpace(mtbl
)));
827 clean
::SelfExplicit(ref typ
) => {
829 args
.push_str(&format
!("self: {:#}", *typ
));
831 args
.push_str(&format
!("self: {}", *typ
));
833 args_plain
.push_str(&format
!("self: {:#}", *typ
));
838 args
.push_str("<br> ");
839 args_plain
.push_str(" ");
841 if !input
.name
.is_empty() {
842 args
.push_str(&format
!("{}: ", input
.name
));
843 args_plain
.push_str(&format
!("{}: ", input
.name
));
847 args
.push_str(&format
!("{:#}", input
.type_
));
849 args
.push_str(&format
!("{}", input
.type_
));
851 args_plain
.push_str(&format
!("{:#}", input
.type_
));
853 if i
+ 1 < decl
.inputs
.values
.len() {
855 args_plain
.push_str(",");
860 args
.push_str(",<br> ...");
861 args_plain
.push_str(", ...");
864 let arrow_plain
= format
!("{:#}", decl
.output
);
865 let arrow
= if f
.alternate() {
866 format
!("{:#}", decl
.output
)
868 format
!("{}", decl
.output
)
871 let mut output
: String
;
873 if arrow
.is_empty() {
874 output
= format
!("({})", args
);
875 plain
= format
!("{}({})", indent
.replace(" ", " "), args_plain
);
877 output
= format
!("({args})<br>{arrow}", args
= args
, arrow
= arrow
);
878 plain
= format
!("{indent}({args}){arrow}",
879 indent
= indent
.replace(" ", " "),
881 arrow
= arrow_plain
);
884 if plain
.len() > 80 {
885 let pad
= format
!("<br>{}", indent
);
886 output
= output
.replace("<br>", &pad
);
888 output
= output
.replace("<br>", "");
890 write
!(f
, "{}", output
)
894 impl<'a
> fmt
::Display
for VisSpace
<'a
> {
895 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
897 Some(clean
::Public
) => write
!(f
, "pub "),
898 Some(clean
::Inherited
) | None
=> Ok(())
903 impl fmt
::Display
for UnsafetySpace
{
904 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
906 hir
::Unsafety
::Unsafe
=> write
!(f
, "unsafe "),
907 hir
::Unsafety
::Normal
=> Ok(())
912 impl fmt
::Display
for ConstnessSpace
{
913 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
915 hir
::Constness
::Const
=> write
!(f
, "const "),
916 hir
::Constness
::NotConst
=> Ok(())
921 impl fmt
::Display
for clean
::Import
{
922 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
924 clean
::Import
::Simple(ref name
, ref src
) => {
925 if *name
== src
.path
.last_name() {
926 write
!(f
, "use {};", *src
)
928 write
!(f
, "use {} as {};", *src
, *name
)
931 clean
::Import
::Glob(ref src
) => {
932 write
!(f
, "use {}::*;", *src
)
934 clean
::Import
::List(ref src
, ref names
) => {
935 write
!(f
, "use {}::{{", *src
)?
;
936 for (i
, n
) in names
.iter().enumerate() {
940 write
!(f
, "{}", *n
)?
;
948 impl fmt
::Display
for clean
::ImportSource
{
949 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
951 Some(did
) => resolved_path(f
, did
, &self.path
, true),
953 for (i
, seg
) in self.path
.segments
.iter().enumerate() {
957 write
!(f
, "{}", seg
.name
)?
;
965 impl fmt
::Display
for clean
::ViewListIdent
{
966 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
969 let path
= clean
::Path
::singleton(self.name
.clone());
970 resolved_path(f
, did
, &path
, false)?
;
972 _
=> write
!(f
, "{}", self.name
)?
,
975 if let Some(ref name
) = self.rename
{
976 write
!(f
, " as {}", name
)?
;
982 impl fmt
::Display
for clean
::TypeBinding
{
983 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
985 write
!(f
, "{}={:#}", self.name
, self.ty
)
987 write
!(f
, "{}={}", self.name
, self.ty
)
992 impl fmt
::Display
for MutableSpace
{
993 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
995 MutableSpace(clean
::Immutable
) => Ok(()),
996 MutableSpace(clean
::Mutable
) => write
!(f
, "mut "),
1001 impl fmt
::Display
for RawMutableSpace
{
1002 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
1004 RawMutableSpace(clean
::Immutable
) => write
!(f
, "const "),
1005 RawMutableSpace(clean
::Mutable
) => write
!(f
, "mut "),
1010 impl fmt
::Display
for AbiSpace
{
1011 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
1012 let quot
= if f
.alternate() { "\"" }
else { """ }
;
1014 Abi
::Rust
=> Ok(()),
1015 Abi
::C
=> write
!(f
, "extern "),
1016 abi
=> write
!(f
, "extern {0}{1}{0} ", quot
, abi
.name()),