Skip to main content

turbopack_dev_server/source/
issue_context.rs

1use anyhow::Result;
2use turbo_rcstr::{RcStr, rcstr};
3use turbo_tasks::{ResolvedVc, Vc};
4use turbo_tasks_fs::FileSystemPath;
5use turbopack_core::introspect::{Introspectable, IntrospectableChildren};
6
7use crate::source::{
8    ContentSource, ContentSourceContent, ContentSourceData, ContentSourceDataVary, ContentSources,
9    GetContentSourceContent,
10    route_tree::{MapGetContentSourceContent, RouteTree},
11};
12
13#[turbo_tasks::value]
14pub struct IssueFilePathContentSource {
15    file_path: Option<FileSystemPath>,
16    description: RcStr,
17    source: ResolvedVc<Box<dyn ContentSource>>,
18}
19
20#[turbo_tasks::value_impl]
21impl IssueFilePathContentSource {
22    #[turbo_tasks::function]
23    pub fn new_file_path(
24        file_path: FileSystemPath,
25        description: RcStr,
26        source: ResolvedVc<Box<dyn ContentSource>>,
27    ) -> Vc<Self> {
28        IssueFilePathContentSource {
29            file_path: Some(file_path),
30            description,
31            source,
32        }
33        .cell()
34    }
35}
36
37#[turbo_tasks::value_impl]
38impl ContentSource for IssueFilePathContentSource {
39    #[turbo_tasks::function]
40    async fn get_routes(self: ResolvedVc<Self>) -> Result<Vc<RouteTree>> {
41        let this = self.await?;
42        let routes = this.source.get_routes();
43        Ok(routes.map_routes(Vc::upcast(
44            IssueContextContentSourceMapper { source: self }.cell(),
45        )))
46    }
47
48    #[turbo_tasks::function]
49    fn get_children(&self) -> Vc<ContentSources> {
50        Vc::cell(vec![self.source])
51    }
52}
53
54#[turbo_tasks::value]
55struct IssueContextContentSourceMapper {
56    source: ResolvedVc<IssueFilePathContentSource>,
57}
58
59#[turbo_tasks::value_impl]
60impl MapGetContentSourceContent for IssueContextContentSourceMapper {
61    #[turbo_tasks::function]
62    fn map_get_content(
63        &self,
64        get_content: ResolvedVc<Box<dyn GetContentSourceContent>>,
65    ) -> Vc<Box<dyn GetContentSourceContent>> {
66        Vc::upcast(
67            IssueContextGetContentSourceContent {
68                get_content,
69                source: self.source,
70            }
71            .cell(),
72        )
73    }
74}
75
76#[turbo_tasks::value]
77struct IssueContextGetContentSourceContent {
78    get_content: ResolvedVc<Box<dyn GetContentSourceContent>>,
79    source: ResolvedVc<IssueFilePathContentSource>,
80}
81
82#[turbo_tasks::value_impl]
83impl GetContentSourceContent for IssueContextGetContentSourceContent {
84    #[turbo_tasks::function]
85    async fn vary(&self) -> Result<Vc<ContentSourceDataVary>> {
86        Ok(self.get_content.vary())
87    }
88
89    #[turbo_tasks::function]
90    async fn get(&self, path: RcStr, data: ContentSourceData) -> Result<Vc<ContentSourceContent>> {
91        Ok(self.get_content.get(path, data))
92    }
93}
94
95#[turbo_tasks::value_impl]
96impl Introspectable for IssueFilePathContentSource {
97    #[turbo_tasks::function]
98    fn ty(&self) -> Result<Vc<RcStr>> {
99        Ok(
100            if let Some(source) = ResolvedVc::try_sidecast::<Box<dyn Introspectable>>(self.source) {
101                source.ty()
102            } else {
103                Vc::cell(rcstr!("IssueContextContentSource"))
104            },
105        )
106    }
107
108    #[turbo_tasks::function]
109    async fn title(&self) -> Result<Vc<RcStr>> {
110        Ok(
111            if let Some(source) = ResolvedVc::try_sidecast::<Box<dyn Introspectable>>(self.source) {
112                let title = source.title().await?;
113                Vc::cell(format!("{}: {}", self.description, title).into())
114            } else {
115                Vc::cell(self.description.clone())
116            },
117        )
118    }
119
120    #[turbo_tasks::function]
121    fn details(&self) -> Result<Vc<RcStr>> {
122        Ok(
123            if let Some(source) = ResolvedVc::try_sidecast::<Box<dyn Introspectable>>(self.source) {
124                source.details()
125            } else {
126                Vc::cell(RcStr::default())
127            },
128        )
129    }
130
131    #[turbo_tasks::function]
132    fn children(&self) -> Result<Vc<IntrospectableChildren>> {
133        Ok(
134            if let Some(source) = ResolvedVc::try_sidecast::<Box<dyn Introspectable>>(self.source) {
135                source.children()
136            } else {
137                Vc::cell(Default::default())
138            },
139        )
140    }
141}